请求、响应与爬虫的相关内容
一、http请求过程
1、请求阶段
客户端请求→DNS解析→建立TCP连接→发送http请求
输入URL,访问host解析,如果没有host解析,就访问dns解析
通俗来说就是,浏览器向网站服务器发送请求,服务器接受并处理请求后返回响应,响应中包含网页源代码等内容,浏览器解析后最终呈现网页界面。
详细步骤:
1、DNS解析 -- 将域名转换为IP地址
2、TCP三次握手 -- 建立可靠连接
3、发送http请求 -- 包含请求行、请求头、请求体
示例:百度
输入百度网址:https://www.baidu.com/


浏览器网络请求各列信息含义如下:
1、Name:请求名称,默认取请求URL的最后一部分(含文件名 + 后缀),若 URL 以斜杠 / 结尾,则显示为域名或路径名称。
补充说明:
- 目的是快速区分不同请求,无需查看完整URL。
- 可手动修改(部分浏览器开发者工具支持),便于调试时标记关键请求。
- 示例:URL 为 https://www.example.com/index.html → Name 显示 index.html;
2、Status(响应状态码):服务器对请求的响应结果标识,由三位数字组成,按首位分为 5 大类,200 仅为 “成功” 类的其中一种。
详细分类与关键状态码:
| 状态码范围 | 类别 | 核心含义 | 常见场景示例 |
|---|---|---|---|
| 1xx | 信息响应 | 服务器已接收请求,需进一步处理 | 100 Continue(预检后继续) |
| 2xx | 成功响应 | 请求正常处理完成 | 200 OK(成功)、204 No Content(成功无返回体) |
| 3xx | 重定向响应 | 需客户端进一步跳转 | 301 永久重定向、304 协商缓存命中(无需下载资源) |
| 4xx | 客户端错误 | 请求存在问题(服务器未处理) | 404 资源不存在、403 权限不足、400 参数错误 |
| 5xx | 服务器错误 | 服务器处理请求时出错 | 500 内部错误、503 服务不可用 |
304 Not Modified 虽不是 200,但属于 “成功复用缓存”,会对应 size 列的 from cache。
3、Type(请求的文档/资源类型):请求所获取资源的 MIME 类型(互联网媒体类型),用于浏览器识别如何解析该资源,document 仅为其中一种(对应 HTML 文档)。
常见类型及含义:
| Type 取值 | 对应资源类型 | 用途 |
|---|---|---|
document |
HTML 文档(text/html) | 页面核心结构,浏览器直接渲染 |
stylesheet |
CSS 样式表(text/css) | 控制页面布局和样式 |
script |
JavaScript 文件(application/javascript) | 页面交互逻辑 |
image |
图片资源(image/png/jpeg/gif 等) | 页面图片展示 |
fetch/xhr |
AJAX/ Fetch 请求(application/json 等) | 异步数据交互(如接口请求) |
font |
字体文件(font/woff2 等) | 页面自定义字体 |
other |
其他未分类资源(如视频、音频) | 如 video/mp4、audio/mpeg 等 |
作用:浏览器根据 Type 决定解析方式(如 HTML 解析为 DOM,CSS 解析为 CSSOM,JS 执行脚本)。
4、Initiator(请求发起来源):标记触发该网络请求的 “源头”,即 “谁发起了这个请求”,帮助定位请求的触发逻辑(尤其调试异步请求时)。
常见来源及含义:
| Initiator 取值 | 触发场景 |
|---|---|
Parser(解析器) |
浏览器解析 HTML 时触发(如 <link rel="stylesheet">、<img>、<script> 标签) |
Script(脚本) |
JavaScript 代码主动发起(如 fetch()、XMLHttpRequest、axios 调用) |
Stylesheet(样式表) |
CSS 样式触发(如 background-image: url(...)、@import url(...)) |
Navigation(导航) |
页面首次加载 / 刷新触发(即主文档 index.html 的请求,由浏览器导航行为发起) |
Other(其他) |
非上述场景(如 Service Worker 触发、用户手动下载文件等) |
部分浏览器(如 Chrome)会显示具体触发文件路径 + 行号(如 main.js:25),直接定位到发起请求的代码位置。
5、Size(资源大小):该请求对应的资源 “实际传输大小”,分为两种情况:从服务器下载(显示具体大小)、从缓存获取(显示 from cache 或 disk cache/memory cache)。
- 显示格式:通常为 xxx B(字节)、xxx KB(千字节)、xxx MB(兆字节),部分浏览器会同时显示 “资源原始大小” 和 “压缩后大小”(如 20KB (gzip: 5KB));
- from cache:通用缓存标识(未区分缓存位置);
- disk cache:从硬盘缓存获取(持久化,关闭浏览器后仍存在);
- memory cache:从内存缓存获取(临时,关闭浏览器后失效,如图片、JS/CSS 等短期复用资源);
- service worker cache:从 Service Worker 缓存获取(前端手动缓存的资源)。
size 是 “传输大小”,而非 “资源原始大小”—— 若服务器开启 Gzip/Brotli 压缩,传输大小会远小于原始大小(如 100KB 的 JS 压缩后可能仅 20KB)。
6、Time(总耗时):从 “发起请求” 到 “完全接收响应” 的总时间,包含网络传输、服务器处理、浏览器等待等所有环节。
时间构成(对应waterfall阶段):总耗时 = 排队时间 + DNS 解析时间 + 建立连接时间 + 等待响应时间 + 内容下载时间
- 作用:评估请求性能的核心指标 ——Time 越长,用户等待时间越长(如接口请求 Time 超过 3 秒可能导致页面卡顿)。
7、waterfall(瀑布流可视化):以横向时间轴为基础,用 “彩色条形块 + 阶段划分” 可视化展示单个请求的完整生命周期,每个阶段的长度对应耗时,直观反映请求在各环节的性能瓶颈。
瀑布流的每个条形块由多个彩色子块组成,每个子块对应一个请求阶段,从左到右依次为:
| 阶段名称 | 颜色标识 | 核心含义 | 耗时影响因素 |
|---|---|---|---|
| Queue(排队) | 灰色 | 请求被浏览器放入队列等待发送(浏览器对同一域名有并发连接限制,通常 6 个) | 同一域名并发请求数过多、前序请求阻塞 |
| Stalled(阻塞) | 灰色 / 浅蓝色 | 排队后到实际发起请求前的等待时间(如等待 TCP 连接建立、缓存检查) | 连接池满、缓存校验耗时 |
| DNS Lookup(DNS 解析) | 深绿色 | 将域名(如 www.example.com)转换为服务器 IP 地址的时间 |
网络环境差、DNS 服务器响应慢 |
| Initial Connection(初始连接) | 橙色 | 建立 TCP 连接的时间(含三次握手),若为 HTTPS 则包含 TLS 握手时间 | 网络延迟、服务器距离、TLS 版本(如 TLS1.3 比 1.2 快) |
| SSL/TLS(HTTPS 加密) | 紫色 | 单独显示 TLS 握手时间(部分浏览器将其合并到 Initial Connection 中) | 加密算法复杂度、服务器 TLS 配置 |
| Request Sent(发送请求) | 蓝色 | 浏览器向服务器发送请求头 / 请求体的时间 | 请求体大小(如 POST 大数据)、网络带宽 |
| Waiting (TTFB)(等待响应) | 红色 | 从发送请求到接收服务器第一个字节响应的时间(Time To First Byte) | 服务器处理速度、网络延迟、接口逻辑复杂度 |
| Content Download(内容下载) | 绿色 | 从接收第一个字节到接收完所有响应数据的时间 | 资源大小、网络带宽、服务器传输速度 |
瀑布流的核心作用:
- 快速定位性能瓶颈:比如红色 Waiting (TTFB) 过长 → 问题在服务器(接口处理慢);橙色 Initial Connection 过长 → 网络或 HTTPS 配置问题;
- 分析请求顺序:比如关键 CSS/JS 被后续请求阻塞 → 需优化资源加载顺序(如预加载、内联);
- 对比缓存效果:从缓存获取的请求(from cache)瀑布流极短(仅显示 Queue 或无阶段),耗时接近 0。
示例:
一个正常的index.html请求瀑布流(HTTPS):
Queue(1ms) → DNS Lookup(5ms) → Initial Connection(20ms) → SSL(15ms) → Request Sent(1ms) → Waiting (TTFB)(80ms) → Content Download(3ms)
总耗时 = 1+5+20+15+1+80+3 = 125ms,其中 TTFB 占比最高(64%),说明服务器处理该请求的时间最长,需优化接口。
总结:这些列信息从 “标识(Name/Type)、结果(Status)、来源(Initiator)、代价(Size/Time)、过程(Waterfall)” 五个维度完整描述了网络请求,其中 Waterfall 是性能优化的核心工具 —— 通过可视化各阶段耗时,能精准定位 “为什么请求慢”,进而针对性优化(如减少 DNS 解析、复用 TCP 连接、优化服务器响应速度、利用缓存等)。
2、响应阶段
服务器处理→返回http响应→浏览器渲染→关闭连接(或保持)
关键点:
- 状态码(200成功、404未找到、500服务器错误)
- 响应内容类型(HTML、JSON、图片等)
(一)核心概念:谁在和谁说话
- 请求方(客户端):主动发起通信的一方,常见载体包括:浏览器(Chrome/Firefox)、手机 App、Postman 工具、后端服务(微服务间调用)等。
- 响应方(服务器):被动接收请求并处理的一方,本质是运行在远程主机上的服务程序(如 Nginx、Tomcat、Node.js 服务),负责处理逻辑、查询数据库、返回数据等。
- 通信协议:双方必须遵守的「语言规则」,最常用的是 HTTP/1.1(目前主流)、HTTP/2(性能更优)、HTTPS(HTTP + SSL/TLS 加密,安全)。
(二)请求(Request):客户端的「需求清单」
请求是客户端发给服务器的「指令」,包含 4 个核心部分:请求行、请求头、空行、请求体(部分请求无请求体)。
(1)结构拆解(以HTTP请求为例)
# 1. 请求行(必填)
GET /api/user/123 HTTP/1.1
# 2. 请求头(可选,键值对形式,描述请求属性)
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# 3. 空行(必填,分隔请求头和请求体)
# 4. 请求体(可选,仅部分请求方法需要,如 POST/PUT)
{"username": "test", "password": "123456"}
(2)各部分详解
①请求行:核心指令(3 个关键信息)
格式:请求方法 + 请求路径 + 协议版本
请求方法:定义客户端要执行的操作,HTTP 1.1 支持 8 种核心方法(常用 5 种):
| 方法 | 作用 | 是否带请求体 | 幂等性(重复执行结果一致) |
|---|---|---|---|
| GET | 查询数据(如打开网页、获取用户信息) | 否 | 是 |
| POST | 提交数据(如登录、注册、上传文件) | 是 | 否 |
| PUT | 全量更新数据(如修改用户全部信息) | 是 | 是 |
| PATCH | 部分更新数据(如仅修改用户昵称) | 是 | 否 |
| DELETE | 删除数据(如删除文章) | 否(可选) | 是 |
- 幂等性:指多次执行同一请求,服务器状态不变(如 GET 多次查询不会改数据,POST 多次提交可能重复创建资源)。
请求路径:服务器上的资源地址,分两种:
- 相对路径:/api/user/123(依赖 Host 头确定完整地址)。
- 绝对路径:https://www.example.com/api/user/123(直接包含域名)。
协议版本:如 HTTP/1.1(主流)、HTTP/2(二进制传输,多路复用)、HTTP/3(基于 QUIC,低延迟)。
②请求头:附加(说明信息)
键值对格式,告诉服务器「请求的上下文」,常用字段:
| 字段名 | 作用 | 示例 |
|---|---|---|
| Host | 目标服务器域名 + 端口(必填) | Host: www.example.com:8080 |
| User-Agent | 客户端身份(浏览器 / 设备信息) | Mozilla/5.0 (Windows NT 10.0; Win64) |
| Accept | 客户端能接收的响应数据格式 | Accept: application/json, text/html |
| Content-Type | 请求体的数据格式(POST/PUT 必带) | application/json(JSON)、multipart/form-data(文件上传) |
| Authorization | 身份认证信息(如 Token、Basic Auth) | Bearer eyJhbGciOiJIUzI1Ni... |
| Cookie | 客户端存储的 Cookie 数据(会话跟踪) | Cookie: sessionId=abc123; username=test |
| Referer | 跳转来源(从哪个页面发起的请求) | Referer: https://www.google.com |
③空行:强制分隔符
请求头和请求体之间必须有一个「空行」,这是 HTTP 协议的硬性规定 —— 服务器通过空行判断请求头是否结束,避免解析错误。
④请求体:携带(数据payload)
仅当请求方法需要提交数据时存在(如 POST/PUT/PATCH),数据格式由 Content-Type 指定,常见格式:
- JSON 格式(最常用,前后端分离首选):{"username": "test", "age": 20}
- 表单格式(application/x-www-form-urlencoded):username=test&password=123
- 文件上传格式(multipart/form-data):包含文件二进制数据 + 表单字段
- 纯文本格式(text/plain):直接传递字符串
(三)响应(Response):服务器的「回复结果」
服务器接收请求后,处理完逻辑(如查询数据库、验证权限),会返回响应给客户端。响应同样包含 4 个核心部分:状态行、响应头、空行、响应体。
(1)结构拆解
# 1. 状态行(必填)
HTTP/1.1 200 OK
# 2. 响应头(可选,描述响应属性)
Server: Nginx/1.21.0
Date: Tue, 18 Nov 2025 10:00:00 GMT
Content-Type: application/json
Content-Length: 88
Set-Cookie: sessionId=def456; Path=/; HttpOnly
Cache-Control: no-cache
# 3. 空行(必填,分隔响应头和响应体)
# 4. 响应体(可选,返回给客户端的实际数据)
{"code": 200, "message": "success", "data": {"id": 123, "username": "test", "age": 20}}
(2)各部分详解
①状态行:核心回复状态(3 个关键信息)
格式:协议版本 + 状态码 + 状态短语
- 协议版本:与请求的协议版本一致(如 HTTP/1.1)。
- 状态码:3 位数字,直观表示请求处理结果(核心中的核心)
- 状态短语:状态码的文字描述(如 OK、Not Found),仅为可读性,服务器判断依赖状态码。
②响应头:附加(回复说明)
键值对格式,告诉客户端「响应的属性」,常用字段:
| 字段名 | 作用 | 示例 |
|---|---|---|
| Server | 服务器软件信息(可选) | Server: Nginx/1.21.0 或 Tomcat/9.0 |
| Date | 响应发送的时间 | Date: Tue, 18 Nov 2025 10:00:00 GMT |
| Content-Type | 响应体的数据格式(客户端解析依据) | application/json、text/html、image/png |
| Content-Length | 响应体的字节大小(帮助客户端判断接收完成) | Content-Length: 88 |
| Set-Cookie | 服务器向客户端设置 Cookie(会话跟踪) | Set-Cookie: sessionId=def456; HttpOnly |
| Cache-Control | 缓存策略(控制客户端是否缓存响应) | Cache-Control: max-age=3600(缓存 1 小时)、no-cache(不缓存) |
| Access-Control-Allow-Origin | 跨域资源共享(CORS)允许的源 | Access-Control-Allow-Origin: *(允许所有域名) |
③空行:强制分隔符
与请求的空行作用一致,分隔响应头和响应体,是 HTTP 协议要求。
④响应体:服务器返回的实际数据
客户端真正需要的内容,格式由 Content-Type 指定,常见场景:
- 网页请求(GET index.html):响应体是 HTML 代码(text/html);
- 接口请求(POST /api/login):响应体是 JSON 数据(application/json);
- 图片请求(GET /img/avatar.png):响应体是图片二进制数据(image/png);
- 错误响应(404/500):响应体可能是错误页面 HTML 或 JSON 错误信息。
(四)、请求与响应的完整流程(以登录操作为例)
1、客户端(浏览器)发起请求:
- 请求行:POST /api/login HTTP/1.1
- 请求头:Host: www.example.com、Content-Type: application/json
- 请求体:{"username": "test", "password": "123456"}
2、服务器接收请求,执行逻辑:
- 解析请求体,验证用户名密码;
- 验证通过,生成 Token;
3、服务器返回响应:
- 状态行:HTTP/1.1 200 OK
- 响应头:Content-Type: application/json、Set-Cookie: sessionId=xxx
- 响应体:{"code": 200, "message": "登录成功", "data": {"token": "eyJhbGciOiJIUzI1Ni..."}}
4、客户端接收响应,处理结果:
- 解析 JSON 响应体,存储 Token;
- 跳转到首页(或继续发起后续请求,携带 Token 认证)。
5、关键注意点
- 无状态性:HTTP 是「无状态协议」—— 服务器不会记住上一次的请求(如登录状态),需通过 Cookie/Token 实现会话跟踪。
- 请求体与方法的匹配:GET/DELETE 方法通常不带请求体(部分服务器不支持),如需传参,应通过 URL 路径(/api/user/123)或查询参数(/api/user?name=test)。
- Content-Type 一致性:请求体的格式必须与 Content-Type 一致(如 JSON 数据对应 application/json),否则服务器无法解析;响应同理,客户端需按 Content-Type 解析响应体。
- HTTPS 的作用:HTTP 传输明文(数据可被抓包窃取),HTTPS 对请求 / 响应加密,保护数据安全(如登录密码、支付信息)。
二、爬虫的原理
简单说:爬虫 = 自动化的「请求发起者」+「响应解析者」,代替人工完成重复的 “打开网页→提取信息→跳转下一页” 流程。
URL队列 → 发起HTTP/HTTPS请求 → 接收服务器响应 → 解析响应内容 → 提取目标数据/新URL →提取数据 →存储数据
↖_______________________提取新URL_________________________↙ →无新URL/满足条件 →停止抓取1、准备URL(爬虫的起点)
URL(统一资源定位符)是互联网资源的唯一地址(如 https://www.example.com/list),爬虫的起点就是「种子 URL 队列」—— 可以是 1 个或多个初始 URL,告诉爬虫 “从哪里开始抓”。
常见来源:
- 人工指定(如要爬取某电商商品列表,直接输入商品列表页 URL);
- 配置文件批量导入(如爬取多个网站,提前写入所有首页 URL);
- 上一轮爬取中提取的新 URL(如爬取列表页后,提取详情页 URL 放入队列,实现 “深度抓取”)。
2、发送请求(模拟浏览器,获取响应)
爬虫与服务器通信的核心,完全遵循 HTTP/HTTPS 协议,爬虫会构造一个标准的 HTTP 请求,发送给目标服务器,获取服务器返回的响应(Response)
(1)请求的核心细节(爬虫 vs 浏览器的差异)
浏览器发起请求时,会自动携带很多「请求头」(如 User-Agent、Cookie),爬虫要想 “伪装成浏览器” 避免被反爬,必须手动构造这些关键请求头:
- User-Agent:告诉服务器 “客户端身份”,爬虫若不设置,服务器会识别为 “非浏览器” 直接拒绝(如返回 403 禁止访问);
- Cookie:携带会话信息(如登录状态、浏览记录),部分网站需登录后才能爬取(如知乎个人主页),爬虫需提前登录获取 Cookie 并加入请求;
- Referer:表明请求来源,部分网站会验证 “是否从自身页面跳转”,需模拟真实跳转来源;
- 其他头:如 Accept(指定接收的响应格式)、Connection(保持连接)等,确保请求与浏览器行为一致。
(2)请求方法的选择
- 大部分数据抓取用 GET 方法(如获取网页、商品详情,仅查询数据,不带请求体);
- 少数场景用 POST 方法(如爬取需要提交表单才能显示的内容,需携带请求体,如 {"page": 2, "size": 20})。
(3)HTTPS 处理
爬虫需支持 HTTPS 协议(自动处理 SSL/TLS 加密),避免因协议不匹配无法建立连接(主流爬虫框架如 Scrapy、Requests 已内置支持)。
3、解析响应(从 HTML/JSON 中提取有用信息)
服务器返回的响应体(Response Body)是 “原始数据”(如 HTML 源码、JSON 字符串、图片二进制),爬虫的核心目标是从这些原始数据中提取「目标信息」(如商品名称、价格、文章内容),这一步叫「解析」。
根据响应体的格式,解析方式分为 3 类:
| 响应体格式 | 适用场景 | 解析工具 / 方法 | 示例目标信息 |
|---|---|---|---|
| HTML 源码 | 爬取网页(如新闻、博客、电商页面) | 1. 正则表达式(简单匹配,如提取链接);2. XPath(按节点路径提取,最常用);3. BeautifulSoup(按标签 / 类名提取,易上手) | 新闻标题、商品价格、作者名 |
| JSON 字符串 | 爬取接口数据(前后端分离网站、App) | 1. 内置 JSON 解析(Python 的 json 模块);2. 框架自带解析 |
用户信息、接口返回的列表数据 |
| 二进制数据 | 爬取文件(图片、视频、PDF) | 直接保存为文件(如 with open("img.png", "wb") as f: f.write(response.content)) |
解析示例(以HTML为例)
假设响应体的HTML片段如下:
<div class="product">
<h3 class="product-name">iPhone 15 Pro</h3>
<p class="product-price">¥9999</p>
<a href="/product/123" class="detail-link">查看详情</a>
</div>
- 用 XPath 提取商品名称://div[@class="product"]/h3/text() → 结果:iPhone 15 Pro;
- 用 BeautifulSoup 提取价格:soup.find("p", class_="product-price").text → 结果:¥9999;
- 提取详情页 URL://div[@class="product"]/a/@href → 结果:/product/123(后续可拼接成完整 URL 放入队列,继续爬取详情页)。
4、存储数据(将提取的信息持久化)
解析出的目标信息是 “内存中的临时数据”,需存储到本地或数据库中,方便后续使用(如数据分析、展示)。常见存储方式:
| 存储方式 | 适用场景 | 优点 | 示例工具 / 格式 |
|---|---|---|---|
| 文本文件 | 简单数据(如链接、纯文本) | 无需额外配置,操作简单 | TXT、CSV(Excel 可打开) |
| 数据库 | 结构化数据(如商品、用户信息) | 支持查询、修改,适合大量数据 | MySQL、MongoDB(非关系型)、SQLite(轻量本地库) |
| 缓存 / 搜索引擎 | 需快速查询的海量数据 | 查询速度快,支持全文检索 | Redis(缓存)、Elasticsearch(搜索引擎) |
示例:将商品信息存入 CSV 文件
商品名称,价格,详情页URL
iPhone 15 Pro,¥9999,/product/123
华为 Mate 60,¥6999,/product/456
三、去重,限速,反反爬
1. URL 去重(避免重复爬取)
爬虫在提取新 URL 时,可能会重复获取同一 URL(如列表页翻页时重复加载同一页),导致:
- 浪费带宽和服务器资源;
- 重复存储数据,占用额外空间。
解决方案:
- 用「集合(Set)」记录已爬取的 URL(判断新 URL 是否在集合中,不在则加入队列);
- 海量数据场景:用 Redis 的 Set 结构(支持分布式去重,适合多爬虫节点协作)。
2. 爬取限速(模拟人类行为,避免给服务器施压)
如果爬虫快速、高频地发送请求(如每秒 100 次),会给目标服务器造成巨大压力,甚至导致服务器崩溃 —— 这种行为属于 “恶意爬取”,服务器会直接封禁爬虫的 IP。
解决方案:
- 给请求加「延迟」(如每爬取 1 个页面,暂停 1-3 秒,用 time.sleep() 实现);
- 控制并发数(如同时只发起 5 个请求,避免并发过高,Scrapy 框架可配置 CONCURRENT_REQUESTS)。
3. 反反爬(突破服务器的反爬虫限制)
服务器会通过各种手段识别并组织爬虫,常见反爬策略及爬虫的应对方法:
| 服务器反爬策略 | 识别逻辑 | 爬虫应对方法 |
|---|---|---|
| 检查 User-Agent | 非浏览器的 User-Agent 直接拒绝 | 伪装成主流浏览器(如 Chrome、Safari)的 User-Agent,甚至随机切换 |
| 检查 Cookie/Session | 未登录或无有效 Cookie 限制访问 | 提前登录获取 Cookie,或模拟登录流程(如用 Selenium 输入账号密码) |
| IP 封禁 | 同一 IP 高频请求,直接封禁 | 1. 用代理 IP 池(切换不同 IP 发起请求);2. 降低爬取频率 |
| 动态页面渲染(JS 加载) | 数据通过 JavaScript 动态生成(HTML 源码中无目标数据) | 1. 分析接口(F12 抓包,直接爬取 JS 调用的 JSON 接口);2. 用 Selenium/Puppeteer 模拟浏览器渲染(执行 JS 后再提取数据) |
| 验证码(图片 / 滑块) | 怀疑是爬虫时,要求输入验证码 | 1. 人工输入(少量场景);2. 对接打码平台(如超级鹰,自动识别验证码) |
| 数据加密(如加密 JSON) | 响应体数据是加密字符串(如 Base64、AES) | 分析前端 JS 代码,找到解密逻辑(如提取密钥、解密函数),爬虫解密后再解析 |
四、会话(Session),Cookies及代理
Cookies
# 示例:使用requests处理cookies
import requests
session = requests.Session()
# 登录获取cookies
login_data = {'username': 'user', 'password': 'pass'}
response = session.post('http://example.com/login', data=login_data)
# 后续请求自动携带cookies
profile = session.get('http://example.com/profile')
会话保持
# 使用Session对象保持会话
session = requests.Session()
# 设置headers
session.headers.update({
'User-Agent': 'Mozilla/5.0',
'Referer': 'http://example.com'
})
# 多个请求共享cookies和session
response1 = session.get('http://example.com/page1')
response2 = session.get('http://example.com/page2')
代理(Proxy)使用
代理类型
- HTTP代理 - 用于HTTP/HTTPS请求
- SOCKS代理 - 支持更多协议类型
- 透明代理 - 不修改请求头
- 匿名代理 - 隐藏客户端IP但标识为代理
- 高匿代理 - 完全隐藏客户端信息
代理配置示例
import requests
# 单个代理
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('http://example.com', proxies=proxies)
# 代理池
proxy_list = [
'http://proxy1.com:8080',
'http://proxy2.com:8080',
'http://proxy3.com:8080',
]
import random
proxy = random.choice(proxy_list)
response = requests.get('http://example.com', proxies={'http': proxy})
完整的爬虫实例
import requests
from bs4 import BeautifulSoup
import time
import random
class SimpleSpider:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
def crawl(self, url, use_proxy=False):
try:
proxies = None
if use_proxy:
proxies = {'http': 'http://your-proxy:port'}
response = self.session.get(url, proxies=proxies, timeout=10)
response.raise_for_status()
# 解析内容
soup = BeautifulSoup(response.text, 'html.parser')
# 提取数据
data = self.extract_data(soup)
# 发现新链接
new_links = self.find_links(soup, url)
return data, new_links
except requests.RequestException as e:
print(f"请求失败: {e}")
return None, []
def extract_data(self, soup):
# 实现具体的数据提取逻辑
titles = soup.find_all('h1')
return [title.get_text().strip() for title in titles]
def find_links(self, soup, base_url):
# 发现页面中的新链接
links = []
for link in soup.find_all('a', href=True):
href = link['href']
# 处理相对链接
if href.startswith('/'):
full_url = requests.compat.urljoin(base_url, href)
links.append(full_url)
return links
# 使用示例
spider = SimpleSpider()
data, links = spider.crawl('http://example.com')
请求频率控制
import time
def polite_crawl(url):
# 添加随机延迟
time.sleep(random.uniform(1, 3))
return requests.get(url)
错误处理
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
except requests.HTTPError as e:
print(f"HTTP错误: {e}")
except requests.ConnectionError as e:
print(f"连接错误: {e}")
except requests.Timeout as e:
print(f"请求超时: {e}")
版权所属:SO JSON在线解析
原文地址:https://www.sojson.com/blog/538.html
转载时必须以链接形式注明原始出处及本声明。
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。
