Python requests库处理登录网站爬取数据时406状态码的解决方案

聖光之護
发布: 2025-11-03 10:39:21
原创
227人浏览过

Python requests库处理登录网站爬取数据时406状态码的解决方案

本教程旨在解决使用python `requests`库对需要登录的网站进行数据抓取时,遇到`406 not acceptable`或请求被拒绝的问题。核心在于通过模拟浏览器行为,在`post`请求中添加必要的http请求头(如`user-agent`、`accept`等),从而成功绕过网站的反爬机制,实现数据的有效获取。

1. 理解406状态码与请求被拒绝的原因

在使用Python的requests库进行网络爬虫时,尤其是针对需要登录的平台进行数据抓取时,可能会遇到请求返回406 Not Acceptable状态码并显示“Rejected”的情况。这通常意味着服务器拒绝了你的请求,因为它认为你的请求不符合其接受的标准。

默认情况下,requests库发送的请求头信息非常简洁,这与主流浏览器发送的请求头有显著差异。许多网站,特别是那些有反爬机制或对安全性要求较高的平台,会检查这些请求头,以判断请求是否来自合法的浏览器用户。如果请求头信息缺失或不符合预期,服务器就可能拒绝该请求。

以下是一个典型的初始尝试代码示例,它可能导致406错误:

import requests
from pprint import pprint

# 假设 username 和 password 从 Config 文件中导入
# from Config import username, password

def main():
    # 目标URL,可能包含登录参数或其他会话信息
    url = 'https://app.plus500.com/trade?innerTags=_cc_&webvisitid=d9cf772d-6ad5-492c-b782-e3fbeaf87654&page=login' \
          '&_ga=2.35401569.1585895796.1661533386-1432537898.1661336007 '

    with requests.session() as session:
        # 尝试使用用户名和密码进行POST请求
        # 注意:这里的auth参数通常用于HTTP基本认证,对于表单登录可能需要POST表单数据
        # 但在某些API接口中,auth也可能被特殊处理。此处我们先沿用原始问题中的用法。
        response = session.post(url, auth=('your_username', 'your_password'))
        pprint(response.text)

if __name__ == '__main__':
    main()
登录后复制

运行上述代码,可能会得到类似以下的“Rejected”响应:

立即学习Python免费学习笔记(深入)”;

('{\n'
 '  "status": "Rejected",\n'
 '  "statusCode": "406",\n'
 '  "supportID": "...",\n'
 '  "ipAddress": "my IP",\n'
 '  "timeStamp": "2022-08-27 12:30:47"\n'
 '}')
登录后复制

这明确指出请求因406状态码被拒绝。

2. 通过模拟浏览器HTTP请求头解决问题

解决406状态码问题的关键在于,让你的Python程序发送的HTTP请求更像一个真实的浏览器请求。这通常通过在请求中添加或修改HTTP请求头来实现。User-Agent是其中最重要的一项,它告诉服务器客户端的类型和版本。此外,Accept、Accept-Encoding、Accept-Language和Connection等头信息也常被用于识别合法请求。

库宝AI
库宝AI

库宝AI是一款功能多样的智能伙伴助手,涵盖AI写作辅助、智能设计、图像生成、智能对话等多个方面。

库宝AI 109
查看详情 库宝AI

以下是修复此问题的具体步骤和代码示例:

2.1 定义模拟浏览器请求头

首先,创建一个字典来存储模拟浏览器的HTTP请求头。这些头信息可以从你常用的浏览器(如Chrome、Firefox)的开发者工具中获取。

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36",
    "Accept-Encoding": "gzip, deflate, br", # 现代浏览器通常也支持brotli (br)
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", # 可以根据需要调整语言偏好
    "Connection": "keep-alive",
    # 更多可能需要的头信息,如Referer, Cookie等,根据实际情况添加
    # "Referer": "https://app.plus500.com/trade?page=login", # 模拟来源页面
    # "Content-Type": "application/x-www-form-urlencoded" # 如果是表单提交,可能需要
}
登录后复制

各项请求头解释:

  • User-Agent: 标识客户端的操作系统、浏览器及其版本。这是服务器判断请求来源是否为真实浏览器的重要依据。
  • Accept-Encoding: 告知服务器客户端支持的编码方式,以便服务器压缩响应数据,提高传输效率。
  • Accept: 告知服务器客户端能够处理的媒体类型。
  • Accept-Language: 告知服务器客户端偏好的语言。
  • Connection: 控制当前事务结束后是否关闭网络连接。keep-alive表示保持连接,以便后续请求复用。

2.2 将请求头添加到POST请求中

将上述定义的headers字典作为参数传递给session.post()方法。

import requests
from pprint import pprint
# from Config import username, password # 假设已定义

def main():
    url = 'https://app.plus500.com/trade?innerTags=_cc_&webvisitid=d9cf772d-6ad5-492c-b782-e3fbeaf87654&page=login' \
          '&_ga=2.35401569.1585895796.1661533386-1432537898.1661336007 '

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
        "Connection": "keep-alive"
    }

    with requests.session() as session:
        # 将 headers 参数添加到 POST 请求中
        response = session.post(url, auth=('your_username', 'your_password'), headers=headers)
        pprint(response.text)

if __name__ == '__main__':
    main()
登录后复制

通过添加这些模拟浏览器的请求头,服务器更有可能将你的请求视为合法请求,从而返回预期的响应内容,而不是406 Rejected。

3. 注意事项与进阶建议

  • 动态获取请求头: 最准确的请求头信息应该从目标网站的真实浏览器请求中获取。使用浏览器的开发者工具(F12),在“网络”(Network)选项卡中,选择对应的请求,查看其“请求头”(Request Headers)部分。复制这些头信息以确保高度模拟。
  • 会话管理: 对于需要登录的网站,使用requests.Session()是最佳实践。它会自动处理cookies,确保在整个会话期间保持登录状态。
  • 处理表单数据: 如果登录是通过提交表单数据(username和password作为表单字段)完成的,那么auth参数可能不适用。你需要构造一个字典作为data参数传递给post方法,并可能需要设置Content-Type: application/x-www-form-urlencoded或application/json。例如:
    login_data = {'username': 'your_username', 'password': 'your_password'}
    headers_with_content_type = {**headers, "Content-Type": "application/x-www-form-urlencoded"}
    response = session.post(login_url, data=login_data, headers=headers_with_content_type)
    登录后复制
  • 反爬机制多样性: 网站的反爬机制远不止检查请求头。可能还包括:
    • Referer检查: 检查请求的来源页面。
    • Cookie检查: 要求携带特定的Cookie。
    • CSRF Token: 跨站请求伪造令牌,通常在登录表单中。
    • JavaScript渲染: 页面内容由JavaScript动态生成,requests无法直接获取,可能需要Selenium或Playwright等无头浏览器工具。
    • IP限制与验证码: 频繁请求可能导致IP被封禁或触发验证码。
  • 合法性与道德: 在进行网络爬虫时,请务必遵守目标网站的使用条款和robots.txt协议,尊重网站数据所有权,避免对服务器造成过大负担。对于交易平台等敏感数据,未经授权的抓取可能涉及法律风险。

总结

当使用Python requests库进行网络爬虫并遇到406 Not Acceptable或请求被拒绝的情况时,通常是由于HTTP请求头信息不完整或不符合服务器预期所致。通过在POST请求中添加模拟浏览器行为的User-Agent、Accept等关键请求头,可以有效地解决这类问题。同时,理解HTTP请求的底层机制以及网站可能采取的反爬策略,是构建健壮且高效爬虫的关键。在实践中,务必结合目标网站的具体情况,灵活调整请求参数,并始终遵循网络爬虫的道德和法律规范。

以上就是Python requests库处理登录网站爬取数据时406状态码的解决方案的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号