与 Web 服务器交互时,无论是 Web 抓取还是 API 工作,Python 请求标头都是一个强大但经常被忽视的工具。这些标头以静默方式进行通信,告诉服务器谁在调用、为什么调用以及应以什么格式返回数据。
在本指南中,我们将介绍有关使用 Python 的请求库设置标头所需了解的所有信息、为什么标头顺序很重要,以及了解标头如何提高 Web 交互的成功率。
对于该库的新手,您可以通过使用 pip install requests 来安装它并按照本指南进行操作。
在 HTTP 中,标头是伴随每个请求和响应的键值对,指导服务器如何处理请求。标头指定期望、格式和权限,在服务器-客户端通信中发挥着关键作用。例如,标头可以告诉服务器发送请求的设备类型,或者客户端是否期望 JSON 响应。
每个请求都会启动客户端(如浏览器或应用程序)和服务器之间的对话,其中标头充当指令。最常见的标头包括:
可以使用 Python 的请求库轻松管理标头,允许您从响应中获取标头或设置自定义标头来定制每个请求。
示例:使用 Python 请求获取标头
在Python中,获取标头的请求可以通过response.headers来完成。
import requests response = requests.get('https://httpbin.dev') print(response.headers) { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "frame-ancestors 'self' *.httpbin.dev; font-src 'self' *.httpbin.dev; default-src 'self' *.httpbin.dev; img-src 'self' *.httpbin.dev https://cdn.scrapfly.io; media-src 'self' *.httpbin.dev; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.httpbin.dev; style-src 'self' 'unsafe-inline' *.httpbin.dev https://unpkg.com; frame-src 'self' *.httpbin.dev; worker-src 'self' *.httpbin.dev; connect-src 'self' *.httpbin.dev", "Content-Type": "text/html; charset=utf-8", "Date": "Fri, 25 Oct 2024 14:14:02 GMT", "Permissions-Policy": "fullscreen=(self), autoplay=*, geolocation=(), camera=()", "Referrer-Policy": "strict-origin-when-cross-origin", "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options": "nosniff", "X-Xss-Protection": "1; mode=block", "Transfer-Encoding": "chunked" }
输出显示服务器发回的标头,其中包含诸如
之类的详细信息示例:设置自定义标头
自定义标头,例如添加用于设备模拟的用户代理,可以使请求显得更加真实:
import requests response = requests.get('https://httpbin.dev') print(response.headers) { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "frame-ancestors 'self' *.httpbin.dev; font-src 'self' *.httpbin.dev; default-src 'self' *.httpbin.dev; img-src 'self' *.httpbin.dev https://cdn.scrapfly.io; media-src 'self' *.httpbin.dev; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.httpbin.dev; style-src 'self' 'unsafe-inline' *.httpbin.dev https://unpkg.com; frame-src 'self' *.httpbin.dev; worker-src 'self' *.httpbin.dev; connect-src 'self' *.httpbin.dev", "Content-Type": "text/html; charset=utf-8", "Date": "Fri, 25 Oct 2024 14:14:02 GMT", "Permissions-Policy": "fullscreen=(self), autoplay=*, geolocation=(), camera=()", "Referrer-Policy": "strict-origin-when-cross-origin", "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options": "nosniff", "X-Xss-Protection": "1; mode=block", "Transfer-Encoding": "chunked" }
此设置有助于确保每个请求都像浏览器一样显示,从而减少触发反机器人措施的机会。在 Python 请求中,设置标头可以让您精确控制与服务器的交互。
使用 Python 请求标头时的一个常见问题是标头名称是否区分大小写。
根据 HTTP/1.1 规范,标头名称不区分大小写,这意味着 Content-Type、content-type 和 CONTENT-TYPE 都是等效的。但是,坚持使用 Content-Type 等标准命名约定而不是替代大小写是一个很好的做法。标准化格式有助于防止混淆,特别是在与可能以不同方式解释标头的第三方 API 或系统集成时。
当 Web 服务器评估请求时,诸如不一致的标头大小写之类的微妙细节可以揭示客户端的本质。许多合法的浏览器和应用程序都遵循特定的大小写约定,例如大写 Content-Type。然而,机器人或脚本可能不会统一遵循这些约定。通过使用非常规大小写分析请求,服务器可以标记或阻止潜在的机器人。
实际上,当使用 python requests set headers 等函数时,Python 的 requests 库会自动处理 header 的大小写规范化。这意味着无论您如何编写标头名称,库都会将其转换为标准化格式,以确保与服务器的兼容性。但是,请注意,虽然标头名称本身不区分大小写,但标头值(例如 Content-Type 中的“application/json”)仍可能按字面解释,并且应准确格式化。
在 Python 的 requests 库中,您可以在任何情况下设置标头,并且库将正确解释它们:
headers = {'User-Agent': 'my-app/0.0.1'} response = requests.get('https://httpbin.dev/headers', headers=headers) print(response.json()) { "headers": { "Accept": ["*/*"], "Accept-Encoding": ["gzip, deflate"], "Host": ["httpbin.dev"], "User-Agent": ["my-app/0.0.1"], "X-Forwarded-For": ["45.242.24.152"], "X-Forwarded-Host": ["httpbin.dev"], "X-Forwarded-Port": ["443"], "X-Forwarded-Proto": ["https"], "X-Forwarded-Server": ["traefik-2kvlz"], "X-Real-Ip": ["45.242.24.152"] }}
如上所示,请求会自动将 content-type 转换为标准 Content-Type。这表明 Python 的 requests 库将为您规范标头名称,从而保持与 Web 服务器的兼容性,无论原始代码中使用的大小写如何。
在大多数标准 API 交互中,使用 Python 请求标头调用发送的标头顺序不会影响功能,因为 HTTP 规范不要求标头的特定顺序。然而,在处理高级反机器人和反抓取系统时,标头顺序在确定请求是否被接受或阻止方面可以发挥意想不到的重要作用。
反机器人系统,例如 Cloudflare、DataDome 和 PerimeterX,通常超越简单的标头验证并分析请求的“指纹”。这包括发送标头的顺序。人类用户(通过浏览器)通常以一致的顺序发送标头。例如,浏览器请求通常可能遵循 User-Agent、Accept、Accept-Language、Referer 等顺序。相反,自动化库或抓取工具可能会以不同的顺序发送标头或添加非标准标头,这可能会成为检测算法的危险信号。
示例:浏览器标头与 Python 请求标头
在浏览器中,您可能会按以下顺序观察标题:
import requests response = requests.get('https://httpbin.dev') print(response.headers) { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "frame-ancestors 'self' *.httpbin.dev; font-src 'self' *.httpbin.dev; default-src 'self' *.httpbin.dev; img-src 'self' *.httpbin.dev https://cdn.scrapfly.io; media-src 'self' *.httpbin.dev; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.httpbin.dev; style-src 'self' 'unsafe-inline' *.httpbin.dev https://unpkg.com; frame-src 'self' *.httpbin.dev; worker-src 'self' *.httpbin.dev; connect-src 'self' *.httpbin.dev", "Content-Type": "text/html; charset=utf-8", "Date": "Fri, 25 Oct 2024 14:14:02 GMT", "Permissions-Policy": "fullscreen=(self), autoplay=*, geolocation=(), camera=()", "Referrer-Policy": "strict-origin-when-cross-origin", "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options": "nosniff", "X-Xss-Protection": "1; mode=block", "Transfer-Encoding": "chunked" }
使用 Python 的 requests 库,标头可能看起来略有不同:
headers = {'User-Agent': 'my-app/0.0.1'} response = requests.get('https://httpbin.dev/headers', headers=headers) print(response.json()) { "headers": { "Accept": ["*/*"], "Accept-Encoding": ["gzip, deflate"], "Host": ["httpbin.dev"], "User-Agent": ["my-app/0.0.1"], "X-Forwarded-For": ["45.242.24.152"], "X-Forwarded-Host": ["httpbin.dev"], "X-Forwarded-Port": ["443"], "X-Forwarded-Proto": ["https"], "X-Forwarded-Server": ["traefik-2kvlz"], "X-Real-Ip": ["45.242.24.152"] }}
标头排序中的这种细微差异可能会向反机器人系统暗示该请求可能是自动化的,特别是与其他信号(例如用户代理格式或缺少标头)结合使用时。
通过分析此顺序,高级检测系统可以识别通常与自动化脚本或机器人相关的模式。当请求与通常的顺序不匹配时,服务器可能会假设它来自机器人,从而可能导致请求被阻止或验证码挑战。
设置 Python 请求标头来模拟浏览器请求时,了解哪些标头在大多数 Web 浏览器中是标准标头会很有帮助。这些标头向服务器通报客户端的功能和偏好,使请求显得更合法。
标准标头模仿浏览器行为,提高请求的成功率。关键标头包括:
为了确保请求模仿真实的浏览器:
浏览器开发者工具 :
代理工具 :
示例:在 Python 中模仿标头
import requests response = requests.get('https://httpbin.dev') print(response.headers) { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "frame-ancestors 'self' *.httpbin.dev; font-src 'self' *.httpbin.dev; default-src 'self' *.httpbin.dev; img-src 'self' *.httpbin.dev https://cdn.scrapfly.io; media-src 'self' *.httpbin.dev; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.httpbin.dev; style-src 'self' 'unsafe-inline' *.httpbin.dev https://unpkg.com; frame-src 'self' *.httpbin.dev; worker-src 'self' *.httpbin.dev; connect-src 'self' *.httpbin.dev", "Content-Type": "text/html; charset=utf-8", "Date": "Fri, 25 Oct 2024 14:14:02 GMT", "Permissions-Policy": "fullscreen=(self), autoplay=*, geolocation=(), camera=()", "Referrer-Policy": "strict-origin-when-cross-origin", "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options": "nosniff", "X-Xss-Protection": "1; mode=block", "Transfer-Encoding": "chunked" }
此请求使用类似浏览器的标头以使交互显得更加自然。通过观察浏览器工具中的标头和标头顺序,您可以在 Python 中自定义这些,使您的请求尽可能接近真实的浏览器请求。
用户代理字符串在服务器如何响应请求方面起着至关重要的作用。它识别发出请求的应用程序、操作系统和设备,从而允许服务器相应地调整其响应。
用户代理字符串通常由浏览器本身生成,并且可能因浏览器版本、操作系统甚至硬件配置而异。
您可以在我们的专题文章中了解有关如何有效使用用户代理进行网页抓取的更多信息:
(https://scrapfly.io/blog/user-agent-header-in-web-scraping/)
当使用带有 POST 请求的 Python 请求标头时,标头在服务器如何解释客户端发送的数据方面发挥着至关重要的作用。 POST 请求通常用于将数据发送到服务器以创建、更新或修改资源,通常需要额外的标头来阐明数据的结构、格式和用途。
Content-Type :表示数据格式,例如 JSON 数据为 application/json,表单提交为 application/x-www-form-urlencoded,或者为 multipart/form-data文件。正确设置可确保服务器按预期解析您的数据。
User-Agent :标识客户端应用程序,这有助于 API 访问和速率限制策略。
授权:安全端点需要对请求进行身份验证,通常使用令牌或凭据。
Accept :指定所需的响应格式(例如 application/json),有助于一致的数据处理和错误处理。
POST 请求标头的使用示例
要以 JSON 格式发送数据,通常将 Content-Type 标头设置为 application/json 并将数据作为 JSON 传递。下面是一个使用 python 请求 post 标头发送 JSON 有效负载的示例:
headers = {'User-Agent': 'my-app/0.0.1'} response = requests.get('https://httpbin.dev/headers', headers=headers) print(response.json()) { "headers": { "Accept": ["*/*"], "Accept-Encoding": ["gzip, deflate"], "Host": ["httpbin.dev"], "User-Agent": ["my-app/0.0.1"], "X-Forwarded-For": ["45.242.24.152"], "X-Forwarded-Host": ["httpbin.dev"], "X-Forwarded-Port": ["443"], "X-Forwarded-Proto": ["https"], "X-Forwarded-Server": ["traefik-2kvlz"], "X-Real-Ip": ["45.242.24.152"] }}
以这种方式使用 python 请求发布标头可确保服务器正确处理您的数据,并可能防止请求被阻止。
当服务器期望来自真实用户的流量时,它可能会检查某些特定于浏览器的标头,这些标头通常仅由实际的 Web 浏览器发送。这些标头有助于识别和区分浏览器与自动脚本,这在某些网站上的反机器人保护中导航时尤其重要。通过配置 Python 请求标头来模仿这些特定于浏览器的模式,您可以使您的请求看起来更人性化,通常会增加请求成功的机会。
DNT(Do Not Track):通知服务器用户的跟踪首选项(1 表示“不跟踪”),使请求更像浏览器。
Sec-Fetch-Site :显示源关系,具有同源、跨站点和无等值,有助于模仿真实的导航上下文。
Sec-Fetch-Mode :定义请求目的,例如导航页面加载,使其可用于复制典型的浏览器行为。
Sec-Fetch-Dest :指示内容类型(文档、图像、脚本),可用于模仿特定资源请求。
Python 请求中特定于浏览器的标头示例:
使用 Python 中的 requests 库发出请求时设置浏览器特定的标头。
import requests response = requests.get('https://httpbin.dev') print(response.headers) { "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "frame-ancestors 'self' *.httpbin.dev; font-src 'self' *.httpbin.dev; default-src 'self' *.httpbin.dev; img-src 'self' *.httpbin.dev https://cdn.scrapfly.io; media-src 'self' *.httpbin.dev; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.httpbin.dev; style-src 'self' 'unsafe-inline' *.httpbin.dev https://unpkg.com; frame-src 'self' *.httpbin.dev; worker-src 'self' *.httpbin.dev; connect-src 'self' *.httpbin.dev", "Content-Type": "text/html; charset=utf-8", "Date": "Fri, 25 Oct 2024 14:14:02 GMT", "Permissions-Policy": "fullscreen=(self), autoplay=*, geolocation=(), camera=()", "Referrer-Policy": "strict-origin-when-cross-origin", "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options": "nosniff", "X-Xss-Protection": "1; mode=block", "Transfer-Encoding": "chunked" }
通过包含这些标头,您可以使您的请求看起来更接近浏览器通常发送的请求,从而降低被标记为机器人或遇到访问限制的可能性。
反机器人检测:浏览器特定的标头帮助请求类似于常规用户流量,使反机器人系统更难标记它们。
增强兼容性:某些网站为类似浏览器的请求提供不同的响应,使这些标头对于限制非浏览器流量的网站非常有用。
请求真实性:使用这些标头模仿浏览器行为可以通过减少阻塞的机会来提高请求成功率。
使用 Python 请求标头时,必须使用有效且格式正确的标头。许多服务器主动监视传入标头以检测异常或不完整的请求。标头无效或缺失的请求(例如缺少用户代理、内容类型设置不正确或标头相互矛盾)是自动或可疑流量的常见信号,可能会导致立即阻塞。
例如,相互矛盾的标头,例如将 Accept: text/html 与 Content-Type: application/json 混合在一起,可能会导致服务器拒绝您的请求,因为这种组合与典型的浏览器行为不符。
此外,一些网站使用人工智能驱动的反机器人工具来检查标题并查明类似机器人的不一致之处。测试标头是否存在潜在问题最好在受控平台上进行。
这些设置标头的实用技巧,例如使用 User-Agent、匹配 Content-Type 以及避免过多的标头,有助于减少检测并最大程度地减少请求阻塞。
设置标头时采取这些预防措施可以显着提高请求的成功率,并帮助您有效绕过潜在的阻塞。
虽然 requests 是一个强大的 HTTP 客户端库,但它并不是一个很好的抓取工具,因为它难以扩展且易于识别和阻止。
ScrapFly 提供网页抓取、屏幕截图和提取 API,用于大规模数据收集。
为了总结本指南,以下是有关 python 请求标头的一些常见问题的解答。
标头在每个请求中传达附加信息,例如预期数据类型、客户端信息和授权详细信息。它们对于传达偏好并确保服务器正确处理请求至关重要。
标头可以帮助绕过反机器人检测、验证请求并确保响应中的数据格式正确。自定义标头以类似于真实的浏览器请求对于抓取和访问受限 API 特别有帮助。
使用浏览器开发人员工具,您可以检查每个请求发送到网站的标头。将这些标头复制到您的 Python 请求中可以帮助您的请求模拟浏览器流量。
使用 Python 请求标头对于 Web 抓取和 API 交互都至关重要。了解如何设置、获取和操作标头可以帮助您创建更有效、更可靠的请求。无论您是处理 GET 或 POST 请求、模仿浏览器标头还是试图避免检测,处理标头的方式都可能决定抓取的成功与否。
通过遵循最佳实践,例如使用标准标头、为 POST 请求设置适当的值以及确保标头顺序,您的请求将能够更好地导航现代 Web 服务的复杂环境。
以上是Python 请求标头指南的详细内容。更多信息请关注PHP中文网其他相关文章!