跳转到正文

Python 爬虫基础原理 ​

在编写爬虫之前,深入理解互联网的底层协议与交互机制至关重要。本指南涵盖了从 HTTP 原理到反爬虫对抗的基础知识,并结合 2025 年的最新技术趋势(如 HTTP/2、TLS 指纹等),为构建高可用爬虫打下坚实基础。

一、HTTP 基本原理 ​

在浏览器中敲入 URL 到获取网页内容之间,网络世界发生了一系列精密的交互。

1.1 HTTP 协议演进 ​

  • HTTP/1.1:最通用的协议,文本格式传输。缺陷是队头阻塞(Head-of-Line Blocking)。
  • HTTP/2:
    • 多路复用 (Multiplexing):单一 TCP 连接并发处理多个请求,大幅降低延迟。
    • 头部压缩 (HPACK):减少传输体积。
    • 爬虫意义:许多现代网站(如 Cloudflare 保护的站点)会检测客户端是否支持 HTTP/2。如果不支持,可能被标记为"非浏览器环境"。
    • 工具:Python httpx 库原生支持 HTTP/2。
    • 📖 RFC 7540 - HTTP/2 规范
  • HTTP/3 (QUIC):
    • 基于 UDP 而非 TCP,彻底解决 TCP 队头阻塞。
    • 反爬趋势:2025 年,越来越多的高防站点启用 HTTP/3。使用不支持 QUIC 的传统库(如 requests)容易被识别。
    • 工具:curl_cffi 等库支持模拟 HTTP/3 指纹。
    • 📖 RFC 9114 - HTTP/3 规范

1.2 URI 和 URL ​

这里我们先了解一下 URI 和 URL,URI 的全称为 Uniform Resource Identifier,即统一资源标志符,URL 的全称为 Universal Resource Locator,即统一资源定位符。

举例来说,https://github.com/favicon.ico,它是一个 URL,也是一个 URI。即有这样的一个图标资源,我们用 URL/URI 来唯一指定了它的访问方式,这其中包括了访问协议 https、访问路径(即根目录)和资源名称 favicon.ico。通过这样一个链接,我们便可以从互联网上找到这个资源,这就是 URL/URI。

URL 是 URI 的子集,也就是说每个 URL 都是 URI,但不是每个 URI 都是 URL。那么,怎样的 URI 不是 URL 呢?URI 还包括一个子类叫作 URN,它的全称为 Universal Resource Name,即统一资源名称。URN 只命名资源而不指定如何定位资源,比如 urn:isbn:0451450523 指定了一本书的 ISBN,可以唯一标识这本书,但是没有指定到哪里定位这本书,这就是 URN。

但是在目前的互联网,URN 的使用非常少,所以几乎所有的 URI 都是 URL,所以一般的网页链接我们可以称之为 URL,也可以称之为 URI。

1.3 超文本 (Hypertext) ​

接下来,我们再了解一个概念 —— 超文本,其英文名称叫作 hypertext,我们在浏览器里看到的网页就是超文本解析而成的,其网页源代码是一系列 HTML 代码,里面包含了一系列标签,比如 img 显示图片,p 指定显示段落等。浏览器解析这些标签后,便形成了我们平常看到的网页,而网页的源代码 HTML 就可以称作超文本。

例如,我们在 Chrome 浏览器里面打开任意一个页面,如淘宝首页,右击任一地方并选择 “检查” 项(或者直接按快捷键 F12),即可打开浏览器的开发者工具,这时在 Elements 选项卡即可看到当前网页的源代码,这些源代码都是超文本。

1.4 HTTP 和 HTTPS ​

在淘宝的首页 https://www.taobao.com/,中,URL 的开头会有 http 或 https,这个就是访问资源需要的协议类型。

  • HTTP:全称是 Hyper Text Transfer Protocol,中文名叫做超文本传输协议,HTTP 协议是用于从网络传输超文本数据到本地浏览器的传送协议,它能保证传送高效而准确地传送超文本文档。
  • HTTPS:全称是 Hyper Text Transfer Protocol over Secure Socket Layer,是以安全为目标的 HTTP 通道,即 HTTP 下加入 SSL 层。

HTTPS 的主要作用可以分为两种:

  1. 建立一个信息安全通道,来保证数据传输的安全。
  2. 确认网站的真实性。

现在越来越多的网站和 APP 都已经向 HTTPS 方向发展。Apple、Google、微信小程序等平台已全面强制或推荐使用 HTTPS。

1.5 HTTP 请求过程 ​

我们在浏览器中输入一个 URL,回车之后便会在浏览器中观察到页面内容。实际上,这个过程是浏览器向网站所在的服务器发送了一个请求,网站服务器接收到这个请求后进行处理和解析,然后返回对应的响应,接着传回给浏览器。响应里包含了页面的源代码等内容,浏览器再对其进行解析,便将网页呈现了出来。

1. 请求 (Request) ​

由客户端向服务端发出,包含 4 部分内容:

  1. 请求方法 (Request Method)

    • GET:请求页面,参数包含在 URL 中,受长度限制。
    • POST:提交表单或上传文件,数据在请求体中,相对安全且无大小限制。
    • 其他:HEAD, PUT, DELETE, OPTIONS 等。
  2. 请求的网址 (Request URL):即统一资源定位符 URL,它可以唯一确定我们想请求的资源。

  3. 请求头 (Request Headers):爬虫伪装的关键。

    • User-Agent:简称 UA,标识操作系统和浏览器版本。如果不加,很可能会被识别出为爬虫。
    • Cookie:维持会话状态的关键字段。
    • Referer:用来标识这个请求是从哪个页面发过来的,常用于防盗链。
    • Host:指定请求的主机 IP 和端口。
    • Content-Type:表示具体请求中的媒体类型信息(如 application/json)。
  4. 请求体 (Request Body):POST 请求承载的数据(表单或 JSON)。

2. 响应 (Response) ​

由服务端返回给客户端,包含三部分:

  1. 响应状态码 (Response Status Code) — 📖 MDN HTTP 状态码完整列表

    状态码含义说明参考链接
    200OK请求成功MDN
    301Moved Permanently永久重定向MDN
    302Found临时重定向MDN
    400Bad Request请求语法错误MDN
    401Unauthorized需要身份验证MDN
    403Forbidden服务器拒绝请求(常见于反爬封锁)MDN
    404Not Found资源不存在MDN
    429Too Many Requests请求过多(反爬常见)MDN
    500Internal Server Error服务器内部错误MDN
    502Bad Gateway网关错误MDN
    503Service Unavailable服务不可用MDN

    💡 爬虫重点关注

    • 403/429 通常意味着被反爬机制拦截,需要更换 IP 或降低频率
    • 5xx 系列错误可能是服务器过载,建议稍后重试
  2. 响应头 (Response Headers)

    • Set-Cookie:服务器告诉浏览器设置 Cookie。
    • Content-Type:文档类型(如 text/html, application/json)。
  3. 响应体 (Response Body)

    • 最重要的内容。请求网页时,它是 HTML 代码;请求图片时,它是二进制数据。这是爬虫解析的目标。

⚠️ 2025 关键反爬特征:TLS 指纹 (JA3)

传统的反爬虫主要检测 User-Agent 或 IP。但在 2025 年,TLS Fingerprinting 已成为标配。

  • 原理:浏览器在建立 HTTPS 连接(TLS Handshake)时,发送的 ClientHello 包包含了一组特定的参数(加密套件顺序、TLS 版本、扩展字段等)。这些参数组合被计算为一个哈希值(如 JA3 Hash)。
  • 检测:
    • Chrome 浏览器的 JA3 指纹是固定的。
    • Python requests 库的 JA3 指纹也是固定的,且与 Chrome 完全不同。
    • WAF(如 Cloudflare)一旦发现 User-Agent 是 "Chrome" 但 JA3 指纹是 "Python Requests",直接拦截。
  • 对抗:
    • 使用支持 TLS 指纹模拟 的库:
      • curl_cffi - 模拟各浏览器 TLS 指纹
      • tls-client - Go 语言 TLS 客户端的 Python 封装
      • Playwright - 微软出品,自带真实浏览器指纹

二、网页基础结构 ​

2.1 三大基石 ​

  1. HTML (骨架):定义网页的内容和结构。
  2. CSS (皮肤):描述网页的布局和样式(层叠样式表)。
  3. JavaScript (肌肉):定义网页的交互和行为,实现实时、动态、交互的功能。

2.2 DOM 树与节点 ​

HTML 文档被视为一棵节点树(DOM Tree):

  • 文档节点 (Document):整个文档。
  • 元素节点 (Element):如 <div>, <p>。
  • 属性节点 (Attribute):如 class="wrapper"。
  • 文本节点 (Text):标签内的文字。

节点间存在 父 (Parent)、子 (Child)、兄弟 (Sibling) 关系,这是解析库(如 XPath, CSS选择器)定位元素的基础。

2.3 CSS 选择器 (Selector) ​

通过 CSS 选择器定位节点是爬虫解析数据的常用手段:

选择器示例描述
ID 选择器#container选择 id="container" 的节点
类选择器.wrapper选择 class="wrapper" 的节点
标签选择器p选择所有 p 标签
嵌套#container .wrappercontainer 内部的 wrapper
属性a[href^="http"]href 以 http 开头的 a 标签

2.4 浏览器指纹技术 (Browser Fingerprinting) ​

除了 IP 和 Cookie,现代网站通过执行 JavaScript 来收集设备特征,生成唯一标识。

  • Canvas Fingerprinting:
    • 通过 JS 绘制一个隐藏的 Canvas 图像。
    • 由于显卡、驱动、操作系统渲染差异,绘制出的像素点在不同设备上是唯一的。
  • WebGL Fingerprinting:利用 3D 渲染 API 获取显卡详细型号。
  • 对抗策略:
    • 使用指纹浏览器(如 Multilogin, GoLogin)。
    • Playwright 配合插件注入随机噪音(但需小心已被识别的噪音模式)。
    • 最稳妥方案:使用真实指纹库或云端真实设备。

三、爬虫基本原理 ​

3.1 核心流程 ​

  1. 获取网页:
    • 构造请求,发送给服务器,获取响应(源代码)。
    • 2025 工具趋势:
  2. 提取信息:
    • 解析源代码,提取目标数据。
    • 方法:
    • AI 辅助:利用 LLM (ChatGPT/Claude) 直接从 HTML 片段自动提取结构化 JSON。
  3. 保存数据:存储到 TXT、JSON、数据库 (MySQL, MongoDB) 或远程服务器。
  4. 自动化:通过程序实现循环抓取、异常处理、自动重试。

3.2 JavaScript 动态渲染 ​

如果在用库抓取网页时,得到的源代码实际和浏览器中看到的不一样,那通常是因为网页采用了 Ajax 或前端模块化工具构建(动态网页)。

对策:

  1. API 逆向:分析后台 Ajax 接口,直接请求数据接口(最高效)。
  2. 浏览器自动化:
    • Selenium:老牌、生态好,但较慢,WebDriver 特征容易被检测。
    • Playwright:微软出品,速度快(支持 CDP 协议),原生支持拦截请求,隐藏特征更容易,是 2025 年的首选。

3.3 攻防对抗升级 ​

  • 验证码:从简单的图形码进化为行为验证(滑块、点选)和无感验证(Cloudflare Turnstile)。
    • 破解:打码平台 API 或 YOLO 等视觉模型。
  • 风控:IP 代理池必须具备高匿性,家庭宽带 IP (Residential Proxies) 价值提升。

四、会话与 Cookies ​

4.1 无状态 HTTP 与状态保持 ​

HTTP 协议是无状态的。为了在请求之间保持状态(如登录状态),诞生了 Session 和 Cookie。

  • Session(会话):存储在服务端,保存用户的相关信息。
  • Cookie:存储在客户端(浏览器),是服务器发给户端的"通行证"。

4.2 登录维持原理 ​

  1. 客户端登录成功,服务器生成 Session,并通过 Set-Cookie 响应头将 Session ID 发给客户端。
  2. 客户端将 Cookie 保存(内存或硬盘)。
  3. 下次请求时,客户端自动在请求头携带 Cookie。
  4. 服务器根据 Cookie 找到对应的 Session,确认用户处于登录状态。

爬虫应用:模拟登录后获取 Cookie,或直接在 Headers 中手动设置 Cookie,即可访问需要登录的页面。


五、代理 (Proxy) 原理 ​

5.1 为什么需要代理? ​

网站会检测同一 IP 的访问频率。如果过高,会返回 403 或验证码(封 IP)。 代理的作用:作为中转站,伪装真实 IP。

Client -> Proxy Server -> Web Server

5.2 代理分类 ​

按匿名度 ​

  • 高匿代理 (High Anonymity):服务端不知道你是代理,也不知道真实 IP。
  • 普通匿名 (Anonymous):服务端知道你是代理,但不知道真实 IP。
  • 透明代理 (Transparent):服务端知道你是代理,也知道真实 IP(无隐私保护作用)。

按协议 ​

  • HTTP/HTTPS 代理:用于访问网页。
  • SOCKS5 代理:单纯传递数据包,支持 TCP/UDP,速度快,用途更广。

六、Ajax 与接口优先策略 ​

3.2 提到动态渲染时可以走「API 逆向」路线。这条路线的重要性值得单独展开——它是现代爬虫效率差异最大的分水岭。

6.1 Ajax 的数据流 ​

Ajax(Asynchronous JavaScript and XML)指在不刷新页面的前提下,由 JavaScript 发起异步请求并局部更新 DOM。今天的传输格式几乎都是 JSON,与名字里的 XML 已无关系。

text
浏览器加载 HTML(空壳)
    → JS 执行,发起 XHR / fetch 请求
    → 服务端返回 JSON
    → JS 操作 DOM,把数据写进页面

关键推论:真正的数据源是那个 JSON 接口,HTML 只是容器。抓接口比抓页面快 10~100 倍,且返回的是结构化数据,无需解析。

6.2 判断页面是否为 Ajax 渲染 ​

python
html = httpx.get(url).text
print("页面上看到的某个具体文字" in html)   # False → 数据由 JS 动态写入

同时对照浏览器:view-source: 看到的是原始 HTML,Elements 面板看到的是渲染后的 DOM。两者不一致,即说明存在动态渲染。

6.3 定位接口的四种方法 ​

方法操作适用
XHR 筛选Network → 勾选 Fetch/XHR → 刷新首选,接口数量少时一眼可见
内容反查Ctrl+Shift+F 全局搜索页面上的具体文字接口很多时最快定位
Initiator点击请求的 Initiator 列跳到发起代码需要追溯参数生成位置
Copy as cURL右键请求 → Copy as cURL完整复刻请求头,避免手抄漏项

6.4 接口参数的四个层次 ​

层次参数形态处理成本
明文参数page、limit、offset、keyword直接构造
凭证参数Cookie、Authorization: Bearer先登录换取,见 反爬对抗
签名参数sign、signature、_signature需 JS 逆向
环境绑定参数依赖 WASM / 浏览器指纹生成逆向成本极高,改用浏览器代跑

判断是否为签名的方法:只改一个业务参数(如页码),观察目标参数是否跟着变。变了是签名,不变是凭证。

6.5 决策:接口还是渲染 ​

💡 一个常被忽略的收益

接口返回的字段经常比页面显示的更多——页面只渲染了其中一部分。走接口路线不仅更快,往往还能拿到页面上根本看不到的数据(如原始时间戳、内部 ID、未展示的统计字段)。


七、爬虫知识地图 ​

本篇是整个爬虫知识体系的入口,各专题的分工如下:

专题解决的问题
基础原理(本篇)HTTP/网页/会话/代理/Ajax 的底层机制
请求库详解用什么发请求、怎么并发、怎么渲染
解析库详解怎么从响应里提取数据
数据存储数据往哪儿放、怎么检索
框架应用规模化后的调度、去重、分布式与部署
反爬对抗被拦截了怎么办:代理、登录态、验证码、内容混淆
JavaScript 逆向加密参数算不出来怎么办
App 数据爬取数据在 App 里、没有网页版怎么办

建议路径:基础原理 → 请求库 → 解析库 → 存储 →(遇到反爬)反爬对抗 →(遇到加密)JS 逆向 →(规模化)框架应用。


📚 参考资料 ​

官方规范文档 ​

文档说明
MDN Web Docs - HTTPMozilla 提供的 HTTP 权威教程
RFC 2616HTTP/1.1 协议规范
RFC 7540HTTP/2 协议规范
RFC 9114HTTP/3 协议规范
RFC 6265HTTP Cookie 规范

Python 爬虫工具库 ​

工具用途文档链接
requests基础 HTTP 客户端官方文档
httpx异步 HTTP 客户端,支持 HTTP/2官方文档
curl_cffiTLS 指纹模拟GitHub
Beautiful SoupHTML/XML 解析官方文档
lxml高性能 XPath/XSLT官方文档
Scrapy爬虫框架官方文档
Selenium浏览器自动化官方文档
Playwright现代浏览器自动化Python 文档

延伸阅读 ​


← 返回 Python 深度研究