📌 专栏:Python 网络爬虫入门到实战(零基础连载全套)🎯 本章定位:爬虫入门防踩坑核心章节。很多新手写好 requests 代码,直接访问网站就 403 被拦截,根源就是缺少请求头伪装、没有超时与异常捕获。本章聚焦基础反爬手段,学会模拟真实浏览器行为,写出健壮、稳定的爬虫请求代码,为后面网页解析实战打下基础。✅ 学习目标
- 理解 HTTP 请求头的作用,掌握请求头常用字段含义
- 掌握 User-Agent(UA)原理,学会浏览器提取 UA 并伪装请求
- 学会 timeout 超时参数配置,防止爬虫长时间卡死
- 熟练使用 try-except 捕获 requests 各类网络异常
- 学习 Cookie、Referer 等其他请求头辅助绕过简单反爬
- 理解基础反爬检测逻辑,分清哪些是简易反爬、哪些是高强度反爬(无法简单绕过)
一、为什么会被网站拦截?
直接使用requests.get(url)不带任何请求头去访问网页,发送的请求头 UA 默认是python-requests/版本号。 网站服务器收到请求,识别到客户端是 Python 爬虫程序,直接返回 403 Forbidden 拒绝访问。
反爬本质:服务器校验请求的身份、行为,判断是不是真实人类浏览器访问。 基础反爬:校验请求头(UA、Referer、Cookie),本章全部可以处理。 进阶反爬:验证码、JS 加密、IP 封禁、指纹校验,本章不涉及,后续章节讲解。
二、请求头 headers 详解
请求头是字典格式,key 是字段名,value 是对应参数,模拟浏览器发给服务器的附加信息。
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Referer": "https://www.baidu.com/", "Accept-Language": "zh-CN,zh;q=0.9", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" }常用请求头字段说明
| 字段 | 作用 |
|---|---|
| User-Agent(UA) | 客户端身份标识,告诉服务器当前是什么浏览器、操作系统,最核心 |
| Accept | 告诉服务器,客户端能接收哪些类型的数据(html、图片、json) |
| Accept-Language | 浏览器支持的语言,模拟中文用户访问 |
| Referer | 来源页面,告诉服务器你是从哪个页面跳转过来的,部分网站校验防盗链 |
| Cookie | 网站会话凭证,登录态、身份标记,部分网站必须携带 |
不是所有网站都需要全部字段,新手优先配置 UA,遇到防盗链再加 Referer。
如何获取真实浏览器 UA
- Chrome 浏览器打开任意网页,按 F12 打开开发者工具
- 切换到 Network(网络)面板,刷新页面
- 随便选中任意一条请求,右侧 Request Headers 里面找到
User-Agent,直接复制。
三、UA 伪装实战代码
import requests url = "https://httpbin.org/headers" # 构造请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } resp = requests.get(url, headers=headers) print(resp.text)运行代码,httpbin 会回显我们发送的请求头,可以看到 UA 已经变成 Chrome 浏览器标识,不再是 python-requests。
四、timeout 超时参数,防止爬虫卡死
网络不稳定、服务器响应缓慢时,requests 请求会一直等待,程序卡死不动。timeout单位:秒。超过设定时间服务器没有返回响应,直接抛出超时异常,终止本次请求。
# 5秒超时,5秒内无响应直接报错 resp = requests.get(url, headers=headers, timeout=5)注意:timeout 不是服务器必须在 5 秒返回完整数据,是连接 + 接收数据的总等待时间。
五、requests 异常分类与 try-except 捕获
爬虫网络请求会遇到大量异常:断网、超时、域名不存在、404、403 等。 如果不捕获异常,程序直接崩溃终止。requests 内置多种请求异常,统一捕获或者细分捕获都可以。
| 异常类型 | 场景 |
|---|---|
| requests.exceptions.Timeout | 请求超时 |
| requests.exceptions.ConnectionError | 网络连接失败,域名错误、断网 |
| requests.exceptions.HTTPError | HTTP 状态码错误,404/403/500 |
| requests.exceptions.RequestException | 所有 requests 请求异常的父类,兜底捕获 |
完整带异常捕获示例代码
import requests url = "https://httpbin.org/headers" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } try: resp = requests.get(url, headers=headers, timeout=5) # 状态码非200时,主动抛出HTTPError异常 resp.raise_for_status() print("请求成功,状态码:", resp.status_code) print(resp.text) except requests.exceptions.Timeout: print("请求超时!") except requests.exceptions.ConnectionError: print("网络连接失败,请检查网址或网络") except requests.exceptions.HTTPError as e: print("HTTP请求错误:", e) except requests.exceptions.RequestException as e: print("其他请求异常:", e)六、进阶:携带 Referer、Cookie 实现简单绕过
部分网站开启防盗链校验,必须携带 Referer 来源头,否则直接返回空白页面或者 403。
import requests url = "https://httpbin.org/headers" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Referer": "https://httpbin.org/", "Cookie": "xxx=xxxx" } resp = requests.get(url, headers=headers, timeout=5) print(resp.text)Cookie 获取方式:F12 开发者工具,Request Headers 中的 Cookie 字段,直接复制。Cookie 常用于需要登录才能访问的页面。
七、基础反爬绕过小结与边界提醒
✅ 本章方法可以解决:
- 只校验 UA 的简单网站拦截
- 防盗链校验(Referer)
- 需要携带 Cookie 访问的页面
❌ 本章方法无法解决:
- JS 动态渲染页面(需要 Selenium/Playwright)
- 图形验证码、滑块验证码
- 短时间高频访问触发 IP 封禁
- 浏览器指纹校验、加密请求参数
爬虫伦理提醒:控制请求频率,不要高频大量请求网站,遵守网站 robots 协议。
八、课后实战习题
- 打开 Chrome 浏览器,复制自己浏览器的 UA,写爬虫代码携带 UA 访问httpbin.org/headers,验证请求头生效。
- 去掉 UA 再次访问,观察请求头变化。
- 给代码增加 timeout 超时参数,设置为 3 秒。
- 完善 try-except 异常捕获,区分超时、连接错误、HTTP 错误三类异常并打印提示。
- 拓展练习:增加 Referer 和 Cookie 字段,观察 httpbin 返回的请求头信息。
九、本章小结
- User-Agent 是服务器识别爬虫最常用的标识,伪装 UA 是爬虫第一道基础操作。
- headers 字典可以携带 UA、Referer、Cookie 等浏览器请求信息,模拟真实访问行为。
- timeout 超时参数必须加上,防止网络卡顿造成程序卡死。
- 使用 try-except 捕获 requests 各类网络异常,
resp.raise_for_status()主动抛出非 200 状态码异常。 - 基础请求头伪装只能应对简单反爬,高强度反爬需要其他方案。