刚开始学习 Python 爬虫时,很多人都会遇到这样的情况:
import requests
url = "https://example.com"
response = requests.get(url)
print(response.status_code)
print(response.text)代码没有报错,甚至返回:
200 OK
但打开 response.text 后却发现:
这时候,问题不一定出在代码逻辑上。
一个经常被新手忽略的地方就是:
请求头 Headers。
本文就从 Python 爬虫入门的角度,讲清楚请求头是什么、哪些字段最重要,以及如何正确设置。
简单来说,当浏览器访问一个网站时,并不是只发送一个 URL。
一次 HTTP 请求通常还会附带很多信息,例如:
这些附加信息,就组成了 HTTP Request Headers,也就是我们常说的:
请求头。
可以把它理解成:
URL 是你要去哪里,请求头则是你在告诉服务器“我是怎样的客户端,以及这次请求希望如何处理”。
腾讯云上的参考文章也重点介绍了 User-Agent、Referer 和 Accept-Language 这几个新手最常用的字段。
使用 requests 直接发送请求时,默认请求头与正常浏览器请求可能存在明显差异。
例如,一个默认 Python 请求可能携带类似:
User-Agent: python-requests/2.x而正常浏览器的 User-Agent 通常包含:
部分网站会根据请求特征决定如何返回内容。
因此,在进行正常的公开网页访问、接口测试或数据采集时,合理设置请求头可以让服务端获得更明确的客户端信息。
但需要注意:
设置请求头并不等于一定可以获取任何网站的数据,也不能保证绕过验证码、访问限制或其他安全机制。
网站还可能综合判断访问频率、Cookie、登录状态、JavaScript 环境以及其他行为特征。
User-Agent,简称 UA。
它用于描述客户端软件环境。
例如:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36"
}发送请求:
import requests
url = "https://example.com"
response = requests.get(
url,
headers=headers,
timeout=10
)
print(response.status_code)对于普通网页请求来说,User-Agent 通常是最先需要了解的字段之一。
不要认为 UA 越长越好。
更重要的是:
请求头应该与自己的实际测试环境和业务场景保持合理一致。
Referer 用于告诉服务器:
这个请求是从哪个页面跳转过来的。
例如:
headers = {
"Referer": "https://www.example.com/"
}某些网站会根据 Referer 进行:
例如,你访问一个网站的详情页时,正常用户可能是:
首页 → 列表页 → 详情页
因此,在合法的自动化测试或公开页面访问中,Referer 有时可以帮助服务端理解请求来源。
HTTP 规范中的字段名称就是:
Referer它历史上拼写就是这样,并不是 Python 拼错了。
很多国际化网站会根据语言设置返回不同内容。
例如:
headers = {
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
}或者:
headers = {
"Accept-Language": "en-US,en;q=0.9"
}这个字段可以告诉服务器:
当前客户端更倾向于接收什么语言的内容。
对于跨境网站测试、多语言产品测试等场景,这一点尤其值得关注。
例如:
测试市场 | Accept-Language |
|---|---|
中国 | zh-CN,zh |
美国 | en-US,en |
日本 | ja-JP,ja |
英国 | en-GB,en |
需要注意的是:
语言设置只是影响网站返回内容的因素之一。
网站还可能参考:
Accept 用于告诉服务器:
客户端能够处理哪些类型的响应内容。
例如:
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}对于普通网页请求,可以根据实际需求设置。
如果你请求的是 JSON API,则可能更关注:
headers = {
"Accept": "application/json"
}所以这里有一个非常重要的原则:
请求头不是复制得越多越好,而是要根据实际请求类型进行配置。
如果你发送的是 POST 请求,还可能需要关注:
Content-Type
例如发送 JSON:
headers = {
"Content-Type": "application/json"
}请求代码:
import requests
url = "https://example.com/api"
data = {
"name": "test"
}
response = requests.post(
url,
json=data,
headers=headers,
timeout=10
)需要注意的是:
当你使用:
json=data时,requests 通常会按照 JSON 方式处理请求数据。
因此,新手不要看到浏览器里有 Content-Type,就不加分析地全部复制。
不同请求的数据格式可能不同。
常见的包括:
application/jsonapplication/x-www-form-urlencodedmultipart/form-data一定要根据实际请求方式判断。
这是爬虫新手经常遇到的问题。
例如:
浏览器已经登录网站。
打开页面:
可以正常查看。
但是 Python 请求:
返回未登录页面。
原因可能就是:
浏览器保存了登录状态,而你的 Python 请求没有。
Cookie 常用于维持会话状态。
更推荐使用:
requests.Session()例如:
import requests
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0"
})
response = session.get(
"https://example.com",
timeout=10
)
print(response.status_code)Session 可以帮助多个请求之间保持会话状态。
对于需要授权访问的系统,应使用官方提供的 API、合法的身份认证方式或明确授权的测试账号,而不是绕过访问控制。
对于普通网页测试,可以从一个简单的配置开始:
import requests
url = "https://example.com"
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0 Safari/537.36"
),
"Accept": (
"text/html,application/xhtml+xml,"
"application/xml;q=0.9,*/*;q=0.8"
),
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
}
try:
response = requests.get(
url,
headers=headers,
timeout=10
)
print("状态码:", response.status_code)
print("响应长度:", len(response.text))
except requests.RequestException as e:
print("请求失败:", e)这里额外加入了:
timeout=10这一点也非常重要。
很多人看到:
200就认为请求成功了。
实际上:
HTTP 200 只说明服务器返回了成功响应。
不代表你一定拿到了想要的数据。
建议同时检查:
print(response.url)
print(response.status_code)
print(response.headers.get("Content-Type"))
print(response.text[:500])看看实际返回的是什么。
有些新手会从浏览器中复制几十个 Header:
Sec-Fetch-*
Sec-CH-UA
Priority
Cache-Control
...然后全部放进代码。
实际上,这样不仅难维护,还可能导致配置之间不一致。
建议:
先保留真正影响请求的核心字段。
通常可以从:
这些开始分析。
不同网站、不同接口的请求类型可能不同。
例如:
HTML 页面:
Accept: text/htmlJSON API:
Accept: application/json如果完全不考虑接口类型,可能导致服务端返回不符合预期的内容。
下面这种写法:
requests.get(url)如果网络连接长时间没有响应,程序可能一直等待。
更推荐:
requests.get(
url,
headers=headers,
timeout=10
)并通过异常处理避免单个请求导致整个程序停止。
这是最大的误区。
Headers 只是 HTTP 请求的一部分。
如果目标网站存在:
单纯修改 User-Agent 并不能解决所有问题。
正确的思路应该是:
先理解网站正常请求的工作方式,再按照授权范围和网站规则设计程序。
最简单的方法就是使用浏览器开发者工具。
以 Chrome 为例:
按:
F12打开开发者工具。
进入:
Network网络面板。
刷新网页。
选择需要分析的请求。
你就可以看到:
这比盲目在网上复制请求头更加可靠。
因为你可以直接看到:
这个页面实际发送了什么请求。
参考文章同样建议通过浏览器开发者工具的 Network 面板观察正常访问时的请求头,再根据实际请求进行配置。
如果你刚开始学习 Python 爬虫,不需要一开始就研究几十个 Header。
建议按照这个顺序:
了解:
请求是谁发送的。
了解:
请求从哪里来。
了解:
客户端希望服务器返回什么类型和语言的内容。
了解:
如何在多个请求之间保持会话状态。
不要只会复制代码。
要学会判断:
当你能看懂一个正常的网络请求时,Python 爬虫的很多问题就会变得更加清晰。
对于 Python 爬虫新手来说,请求头并不神秘。
你可以简单理解为:
URL 决定你访问哪里,Headers 决定你如何向服务器描述这次请求。
最常见的几个字段:
请求头 | 主要作用 |
|---|---|
User-Agent | 描述客户端类型 |
Referer | 描述请求来源页面 |
Accept | 描述可接受的内容类型 |
Accept-Language | 描述语言偏好 |
Content-Type | 描述请求数据类型 |
Cookie | 维持会话状态 |
最后记住一句话:
不要盲目复制请求头,也不要认为 Header 可以解决所有访问问题。
正确的方法是:
观察正常请求 → 理解每个字段 → 根据实际接口配置 → 设置超时和错误处理 → 控制访问频率 → 遵守网站规则。
对于刚开始学习 Python 数据采集的用户来说,先把 User-Agent、Referer、Accept-Language、Cookie 和 Session 这些基础知识搞清楚,就已经迈出了非常重要的一步。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。