请求html有两种response返回方式
一种是服务器渲染,便是服务器一次性把你所要的数据和html一起返回并结合,于是你直接请求resquest便可以直接爬取
另一种是客户端渲染,第一次你只能爬到裸框架,然后服务器会对你的后续请求不断发送数据,在你的客户端本地和html结合,这时候F12的元素和框架源代码是分开的,需要你去找到数据的请求才能找到你想要的数据,而不是框架源代码
因为剩余内容是主要由后期JavaScript生成的,直接生成到元素里
HTTP协议把一条消息分为三大块内容,无论是请求还是响应都是三块内容
请求:
1. 请求行 -> 请求方式(get/post) 请求url地址 协议
2. 请求头 -> 放一些服务器要使用的附加信息 (你的客户端是什么,)
3.
4. 请求体 -> 一般放一些请求参数(你的具体需要)
响应:
1. 状态行 -> 协议 状态码
2. 响应头 -> 放一些客户端要使用的一些附加信息(cookie之类的、加密秘钥)
3.
4. 响应体 -> 服务器返回的真正客户端要使用的内容(HTML,json)等
请求头中最常见的一些重要内容(爬虫需要):
1. User-Agent: 请求载体的身份标识(用啥发送的请求)
2. Referer: 防盗链(这次请求是从哪个页面来的? 反爬会用到)
3. cookie: 本地字符串数据信息(用户登录信息, 反爬的token)
响应头中一些重要的内容:
1. cookie: 本地字符串数据信息(用户登录信息, 反爬的token)
2. 各种神奇的莫名其妙的字符串(这个需要经验了, 一般都是token字样, 防止各种攻击和反爬)
请求方式,一般分为post/get (要关注区别,可以问gpt)
post : 隐式提交,用于修改信息,上传信息
get:显式提交,用于提取信息,查询信息,如地址栏里的
但不管是哪种,都记得要记得关闭response,response.close象征你的网站访问关闭,如果不关代表你同时会请求多个网页,多了会堵塞
或者是在请求头里加入Connection:‘close’,这个默认是‘keep-alive’的
GET 和 POST 的设计理念:
-
GET 设计用于"获取"资源,遵循幂等性原则(多次请求结果相同),无传统Payload(传递参数到url里)和body数据长度受限于URL长度限制,数据显式在地址栏,不适合敏感信息(虽然 GET 理论上可以有 body,但不推荐使用)
-
POST 设计用于"提交"数据,会改变服务器状态,数据放在body里,可以大量传输,不显示与URL,相对安全,可以传输多种数据类型(JSON、XML、文件等)
在post模式里,会有负载(Payload)
-
负载(Payload)的原始含义:
- 在计算机网络中,Payload 最初来源于运输领域,指的是真正需要运送的货物
- 在数据传输中,Payload 指的是实际需要传输的数据部分,不包括协议头等元数据
- 就像货车运输,车身是协议头,货物才是 Payload
具体用什么可以在网络里查看
requests.get(
url, # 请求的URL
params=None, # URL参数字典
headers=None, # 请求头字典
cookies=None, # Cookie字典
auth=None, # 认证元组 (username, password)
timeout=None, # 超时时间(秒)
allow_redirects=True, # 是否允许重定向
proxies=None, # 代理设置字典
verify=True, # SSL证书验证 ,你对服务器的验证,服务器不安全的时候会停止
cert=None, # SSL客户端证书
stream=False, # 是否立即下载响应内容
json=None # JSON数据
)
requests.post(
url, # 请求的URL
data=None, # 请求体数据
json=None, # JSON格式数据
params=None, # URL参数
headers=None, # 请求头
cookies=None, # Cookie
files=None, # 文件上传
auth=None, # 身份认证
timeout=None, # 超时设置
allow_redirects=True, # 是否允许重定向
proxies=None, # 代理设置
verify=True, # SSL证书验证
stream=False, # 是否立即下载响应内容
cert=None # SSL客户端证书
)
想爬取搜索后的页面,要把网址搜索内容后面的参数都删掉
1. **典型的搜索URL示例**:
原始URL:
https://www.baidu.com/s?wd=python&rsv_spt=1&rsv_iqid=0xc89f535800052f46&issp=1&f=8&rsv_bp=1&rsv_idx=2
简化后:
https://www.baidu.com/s?wd=python
2. **为什么要删除多余参数:**
- 这些参数大多是用于追踪和统计的,比如:
- 用户来源
- 搜索时间
- 会话ID
- 用户行为数据
- 浏览器信息等
3. **保留多余参数的问题:**
- 可能导致反爬机制识别
- URL过长不便于管理
- 相同内容可能因参数不同而被重复爬取
- 有些参数是临时的,过期后可能导致请求失败
4. **只保留核心参数的好处:**
- 更简洁的URL
- 降低被反爬的风险
- 提高爬虫效率
- 便于维护和调试
比如百度搜索,通常只需要保留:
- wd(搜索关键词)
其他的rsv_spt、rsv_iqid等参数都可以删除。
- 为什么会有这些参数:
- 用户行为分析
- 搜索质量优化
- 反爬虫机制
- 个性化推荐
- 广告投放追踪
详细解释URL的完整格式:
scheme://username:password@hostname:port/path?query_parameters#fragment
详细解释每个部分:
-
scheme(协议):
- 如:http://, https://, ftp://
- 必须以冒号和两个斜杠结束(://)
-
username:password(身份验证,可选):
- 如:user:pass@
- 现在较少使用,因为安全性问题
-
hostname(主机名):
- 如:www.example.com
- 可以是域名或IP地址
-
port(端口,可选):
- 如::80, :443
- 默认端口可省略(HTTP默认80,HTTPS默认443)
- 端口决定了是用什么服务,比如: 80端口通常用于HTTP服务 443端口用于HTTPS服务 21端口用于FTP服务 3306端口常用于MySQL数据库
-
path(路径):
- 如:/blog/article/123
- 以斜杠(/)分隔的路径段
- 路径在现代服务器里主要是 逻辑路径 而且是多样定义的,可以是数据库查询,可以是功能的启动,也可以是真实文件路径
-
API接口路径:
/api/users/login -> 处理用户登录 /api/products/search -> 搜索商品
B. 数据库查询路径:
/users/123 -> 查询用户ID为123的信息 /orders/2024 -> 查询2024年的订单
C. 功能触发路径:
/system/backup -> 触发系统备份 /cache/clear -> 清除系统缓存
D. 静态资源路径(实际文件):
/images/logo.png -> 实际的图片文件 /css/style.css -> 实际的样式文件
E. 页面路由路径:
/home -> 首页 /about -> 关于页面 /products -> 产品列表页
-
query_parameters(查询参数):
- 以问号(?)开始
- 格式:key1=value1&key2=value2
- 多个参数用&符号连接
- 用于传递搜索条件或其他参数
-
fragment(片段,可选):
- 以井号(#)开始
- 用于指向页面特定部分
编码问题:
Python在内存里字符,要求操作效率高,得用对齐的内存长度,可以用随机访问,每次步长基本一致,一般是Unicode,也就是utf-16,意味着最短是两个字节16bit,一般是2字节或者4字节,操作快但会导致短字符也要一样长(utf-8则是最短是一个8位bit,所以可以自由变长)
但是Python在存储和传输字符时得用utf-8或者gbk版本(变长字符),让编码集变的简单
可以压缩空间,所以用open或者print都得要重新编码。
在网络爬虫里,是先把网络的html,的utf-8或者gbk形式,成字节流(有utf-8规则编码的二进制)传回Python,然后解码decode码成Unicode到Python里,Python的decode就是解码成Unicode
utf-16,网页编码一般可以在网页源代码的开头找到编码信息
当然你可以用text来让response对象自己识别转换编码解码成Unicode,也可以用decoding
在输出print时让项目有默认输出编码,但是open存储还是得手动设置把Unicode去encoding编码哪种编码,不过open的encoding=是默认用操作系统决定,而且这个是同时关联encoding和decoding
GBK 全称是 "Guojia Biaozhun Kuozhan" (国家标准扩展):
- 是对 GB2312 的扩展
- 包含了:
- 所有 GB2312 的字符
- 繁体中文字符
- 日文假名
- 其他符号
UTF-8 全称:
Universal Character Set/Unicode Transformation Format-8
- Universal Character Set:通用字符集
- Transformation Format:转换格式
- 8:使用8位(1字节)为编码单元
UTF-8特点:
# 可变长度编码方案:
- ASCII字符:1字节
- 欧洲字符:2字节
- 中文等字符:3字节
- 其他罕见字符:4字节
# 示例
'A'.encode('utf-8') # 1字节:0x41
'€'.encode('utf-8') # 2字节:0xE2 0x82 0xAC
'中'.encode('utf-8') # 3字节:0xE4 0xB8 0xAD