内容回顾
爬虫其实就是模拟浏览器发送请求获取相应数据
能够帮助我们更加快速更加精确的获取我们想要的数据,能极大地提升我们的工作效率
1.模拟请求
2.获取数据/解析数据
3.存储数据
规定了浏览器与服务端之间数据交互的格式
四大特性
1.基于请求响应
2.基于TCP/IP作用于应用层上的协议
3.无状态
4.无连接
数据格式
请求数据格式
请求首行
请求头
请求体
响应数据格式
响应首行
响应头
响应体
响应状态码
用简单的数字来表示一串中文意思
1XX:服务端已经接收到了你的请求正在处理,你可以继续提交数据
2XX:服务端成功响应了对应的数据(200 OK)
3XX:重定向(原本想访问A突然跳到了B)
4XX:404请求资源不存在,403请求不符合条件
5XX:服务器内部错误500
# 公司内部也会自定义独有的响应状态码
例10001 请求超时
10002 链接断开
get请求
朝别人要数据 可以携带一些不敏感的数据
url?username=jason&password=123
post请求
朝别人提交数据 可以携带任意大小任意类型的数据
post请求是在请求体里面携带的数据
我们用浏览器看到的花里胡哨的页面背后,其实就是有一堆HTML标签构成的
也就意味着我们通过代码获取到的页面数据其实也就是一堆HTML标签
HTML全称"超文本标记语言"
所有的网址如果想要让浏览器正常展示出来页面,就必须遵循HTML语法
前端三剑客
HTML 网页的骨架
CSS 网页的样式
JS 网页的动态效果
文档结构
html
head
body
head内常见标签
title
script
link
style
body内常见标签
h1~h6 标题标签
div 区域标签
span 普通文本
a 链接标签
img 图片标签
获取用户数据并提交到服务器
form标签
action
数据提交给谁
method
请求方式
input标签
select标签 下拉框
textarea 大段文本框
今日内容
正则表达式
它是一门独立的学科,不属于其他任何知识点
所有的编程语言都可以使用正则表达式
如果我们想在python中使用正则表达式需要借助于re模块(爬虫相关模块)
用一些特殊符号的组合去字符串里面筛选出符合符号特征的内容
# 校验手机号
1.校验手机号的开头
2.校验手机号的位数
3.校验必须是纯数字
'''用python逻辑代码实现'''
# 获取用户输入的手机号
phone = input('please input your number>>>:').strip()
# 1.是否是纯数字
if phone.isdigit(): # 字符串里面如果是纯数字就返回True不是返回False
# 2.判断位数
if len(phone) == 11:
# 3.判断手机号开头 11 13 14 15 18
if phone.startswith('11') or \
phone.startswith('13') or \
phone.startswith('14') or \
phone.startswith('15') or \
phone.startswith('18'):
print('手机号正确')
else:
print('手机号格式错误')
else:
print('手机号必须是11位')
else:
print('手机号只能是数字')
'''用正则表达式书写'''
import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
字符组
[0-9] # 匹配数字
[a-z] # 匹配小写字母
'''
字符组在匹配的时候是单个单个字符依次匹配
'''
字符组:[字符组]
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
字符分为很多类,比如数字、字母、标点等等。
假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。
字符
特殊符号
. 匹配换行符意外的任意字符
\d 匹配数字
^ 匹配字符串的开头
^a 匹配字母a但是这个a必须位于字符串的开头
$ 匹配字符串的结尾
a$ 匹配字符a但是这个a必须位于字符串的结尾
| 或
a|b 匹配字符a或者字符b
() 给正则表达式组成一个组 不影响匹配
[^] 取反操作
[a-z]匹配所有的小写字母
[^a-z]匹配除了小写字母意外的任意字符
'''
^与$连用可以明确的限制待匹配的字符
^jason$ 这个字符串必须仅仅是jason才可以
'''
量词
量词的出现能够是我们的正则表达式一次性匹配多个字符
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
"""
正则表达式默认都是贪婪匹配(尽可能往多的匹配)
"""
量词不能单独使用,一定要配合正则符号
实际应用
海. 海燕海娇海东 海燕
海娇
海东 匹配所有"海."的字符
^海. 海燕海娇海东 海燕 只从开头匹配"海."
海.$ 海燕海娇海东 海东 只匹配结尾的"海.$"
李.? 李杰和李莲英和李二棍子 李杰
李莲
李二
李.* 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子
李.+ 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子
李.{1,2} 李杰和李莲英和李二棍子 李杰和
李莲英
李二棍
\d+ hj213hj312h3j 213
312
3
贪婪匹配与非贪婪匹配
待匹配的字符串
<script>hello world</script>
***************************************************
# 正则1 贪婪匹配
<.*>
"""
贪婪匹配会一直往后查找
<script>hello world</script>
"""
# 正则2 非贪婪匹配(在量词的后面加上一个问号就会由贪婪变成非贪婪)
^<.*?>
"""
<script>
"""
***************************************************
复杂的正则匹配
^[1-9]\d{13,16}[0-9x]$
字符串必须是数字1-9开头
后面可以出现13位到16位的数字
必须是以数字0-9或者字母x结尾
^[1-9]\d{14}(\d{2}[0-9x])?$
字符串必须是数字1-9开头
后面必须再跟14位数字
再跟两位数字
最后一位数字或者字母x结尾
"""
我们以后遇到复杂的正则表达式需要自己手写,直接百度即可
http://tool.chinaz.com/regex/
"""
转义符
由于斜杠和一些字母的组合有特殊的含义,但是我们有时候并不需要这些特殊含义就是写什么就是什么
\n 并不能匹配到字符 \n
\\n 才能匹配正常的字符 \n
在python中我们习惯用字母r来取消特殊含义
re模块
import re
# ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
# print(ret)
"""
findall分组优先展示
(baidu|oldboy)
会优先展示出括号内正则表达式匹配到的内容
取消分组优先展示
(?:baidu|oldboy)
"""
# res = re.search('a','jason egon alex')
"""
只要找到一个符合正则的字符 就立刻结束
"""
# res = re.match('a','jason egon alex')
"""
会从字符串的开头找 如果不符合后面直接不找了
"""
requests模块
该模块可以通过代码模拟浏览器发送请求
下载
pip3 install requests
基本使用
import requests
# 朝目标网址发送get请求获取数据
res = requests.get('https://www.baidu.com')
# print(res) # <Response [200]>
# print(res.status_code) # 200 两者都是用来查看响应状态
# print(res.text) # 获取get请求响应的页面内容(字符串)
print(res.content) # 获取get请求响应的页面内容(二进制)
with open(r'a.html','wb') as f:
f.write(res.content)
'''
requests模块可以模拟很多请求方法
requests.get()
requests.post()
...
'''
防爬措施
1.最简单的
校验你是不是一个浏览器
# 就是去你的请求头里面查看有没有一个键值对
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
'''上述键值对是专门用来标识你是否是一个浏览器'''
破解方式
在你的请求头里面加上上述键值对即可
import requests
res = requests.get('https://dig.chouti.com/',
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
)
with open(r'b.html','wb') as f:
f.write(res.content) # 只能拿到HTML代码 CSS和JS我们无法直接获取和执行