【一】基础概念
【1】爬虫
(1)定义
- 爬虫,又称为网络爬虫或网络蜘蛛
- 是一种按照一定规则 自动抓取 ** 万维网信息的程序或者脚本**
(2)流程
- 发送请求
get
还是post
- 请求头内容等
- 获取响应
text
还是content
还是json
等
- 解析响应
BeautifulSoup
、lxml
、re
等
- 存储数据
mysql
、csv
、json
等
(3)常见反爬措施
- 频率限制、封
IP
或者封账号 - 请求头携带加密信息
Referer
(来源页面地址)和User-Agent(浏览器标识)
- 设置验证码
JS
加密- 使用
javascript
对核心代码加密 - 函数和变量名的改变:
ers()
变为function()
等
- 使用
- 绑定手机设备
(2)分类
- 分类一
- 通用爬虫和定向爬虫
- 区别:是否针对特定网站
- 分类二
- 基于规则的爬虫和基于机器学习的爬虫
- 区别:依赖于指定的规则,还是机器学习学习算法自动优化
- 分类三
- 单机爬虫和分布式爬虫
- 区别:是否在多个服务器上同时运行
(3)注意事项
- 爬虫需要合法、合法、合法
- 爬虫的访问速度要限制
- 特殊环境的爬虫需要稳定性,保证异常不会终止程序
- 数据量不同,存储方式不同
【2】HTTP协议
(1)四大特性
- 基于请求-响应
- 客户端发送请求
- 等待服务端响应
- 基于
TCP/IP
层之上- HTTP协议是应用层协议
- 依赖于底层的传输协议
- 无状态
- 不会保存客户端状态信息
- 每次访问都当成新用户
- 常见解决方案:Cookie、Session、Token等
- 无连接
- 每次请求都需要建立一个连接
- 在请求处理后关闭连接
- HTTP1.1引入持久连接
- 后续允许一个TCP连接发送多个请求和响应
(2)HTTP状态码
- 1 xx:信息状态码
- 表示服务器已经接收到请求并正在处理,但需要进一步的操作才能完成请求
- 例如:100 Continue状态码表示客户端应继续发送请求
- 2 xx:成功状态码
- 表示请求已被服务器接收、理解和处理
- 例如:200 OK状态码表示请求已经成功,服务器正常处理并返回了请求的资源
- 3 xx:重定向状态码
- 表示表示客户端需要进一步的操作才能完成请求,通常意味着需要重定向到另一个位置
- 例如:301 Moved Permanently状态码表示请求的资源已被永久的移动到新的URL
- 4 xx:客户端错误状态码
- 表示客户端发送的请求错误或无法完成
- 404 Not Found状态码表示服务器无法找到请求的资源
- 5 xx:服务器错误状态码
- 表示服务器在处理请求时发生了错误
- 503 Service Unavailable状态码表示服务器暂时无法处理请求,可能由于过载或维护
(3)HTTP请求
- 请求首行
- 请求的方法(get\post)、请求的URL和HTTP协议的版本
- 请求头
- 关于请求的各种附加信息,由字段名和字段值组成
- 字段名和字段值之间用冒号加空格分割
- 而每个字段结束后都有一个
CRLF
(回车换行)
- 如:User-Agent(用户代理)、Accept-Language(接收的语言)等
- 关于请求的各种附加信息,由字段名和字段值组成
- 空行
- 用于分割请求头和请求体
- 必须有
- 请求体
- 请求体可选,通常用于POST请求或PUT请求,包含发送给服务器的数据
- 请求体的格式
urlencode
形式的键值对Json
格式formdata
格式
(4)HTTP响应
- 响应首行
- 通常包含HTTP协议版本、状态码以及描述信息
- 响应头
- 包含响应的元数据,如服务器类型、日期、内容类型等
- 响应头由字段名和字段值组成。两者之间用冒号加空格分隔
- 空行
- 用于分割响应头和响应体
- 必须有
- 响应体
- 包含实际返回给用户的数据
- 可能是HTML文章、图片、Json数据等
(5)get请求和post请求对比
- get请求
- get请求通常没有请求体,数据通过URL传递
- 由于数据会附加在URL后面,因此大小受限于浏览器和服务器对URL长度的限制
- 触发的方式:网页中单击连接(a标签)、地址栏输入地址并回车、form表单默认触发get请求等
- post请求
- post请求将数据放在请求体中
- 理论上可以发送大量信息,具体大小取决于服务器配置
- 触发的方式:form表单改为POST提交数据、上传文件、发送
API
请求等
【二】requests模块
【1】引言
-
requests模块基于内置模块urllib使用Python语言编写
- 采用Apache2 Licensed开源协议的HTTP库
-
安装
pip install requests
【2】发送请求
(1)请求参数
- url:发送请求地址,字符串
- headers:请求头,字典
- Host:指定目标服务器域名或IP
- User-Agent:表示发送请求用户代理(通常是浏览器)
- 可使用
fake_useragent
模块的UserAgent
对象随机random
生成
- 可使用
- Accept:指定客户端能够接收的内容类型
- Accept-Language:指定客户端期望接收的语言
- Accept-Encoding:指定客户端支持的编码内容
- Content-Type:指定请求体的媒体类型
- Content-Length:指定请求体的长度(单位字节)
- Cookie:向服务器传递保存在浏览器中的Cookie信息
- 字符串格式
- Referer:指定源地址,可以用于图片防盗链等
- Location:在重定向响应中,提供重定向的目标URL
- Cache-Control:指定请求或响应的缓存策略
- params:携带参数,字典
- cookies:放在外面就要求是字典格式了,还可以是
requets.get().cookies
对象
(2)get请求-百度示例
-
分析百度的URL地址栏发现,wd后面携带是搜索内容
-
https://www.baidu.com/s?wd=%E5%91%A8%E6%98%9F%E9%A9%B0
-
可以使用urlib模块的parse进行转换
-
encoded_text = urllib.parse.quote(chinese_text.encode('gbk')) decoded_text = urllib.parse.unquote(encoded_text).decode('gbk')
-
# 百度发送携带数据的get请求
import requests
from fake_useragent import UserAgent
# 使用随机生成发送请求用户代理
user_agent = UserAgent().random
headers = {
'User-Agent': user_agent,
}
# 指定访问地址
url = "https://www.baidu.com/?="
# 携带参数
params = {
"wd": "周星驰",
}
# 发送请求
res = requests.get(url, headers=headers, params=params)
print(res.text)
(3)get请求-京东示例
- 在登录成功的情况下
- 我们随便找个地址访问【爱国者爱国者GT8智能手表 黑色】爱国者(aigo)智能手表GT8男款健康监测血压心率多功能通话圆盘运动手表 黑色【行情 报价 价格 评测】-京东 (jd.com)
- 现在我们退出登录以后再次直接访问这个链接,会发现到了登录界面
- 即京东的详情界面是需要携带参数才可以访问的
- 登录以后查看详情界面抓包工具中的请求头
- 可以发现携带了cookie
- 现在尝试携带cookie爬虫访问
- 有时会访问失败(前方拥挤请刷新重试)
import requests
from fake_useragent import UserAgent
# 使用随机生成发送请求用户代理
user_agent = UserAgent().random
headers = {
'User-Agent': user_agent,
# 方式一
# cookie直接复制放在headers中
"Cookie": "",
}
# 指定访问地址
url = "https://item.jd.com/100058029494.html"
# 发送请求, 方式一
res = requests.get(url, headers=headers)
print(res.text)
import requests
from fake_useragent import UserAgent
# 使用随机生成发送请求用户代理
user_agent = UserAgent().random
headers = {
'User-Agent': user_agent,
}
# 指定访问地址
url = "https://item.jd.com/100070683706.html"
# 方式二
# cookie是一个字典
# 将浏览器的cookie进行字符串处理
def cookie_operate(cookies_str)