Python使用requests请求CME原油行情页读超时的解决方案
问题原因
目标站点CME Group配置了基础反爬规则,默认requests库发起请求时携带的User-Agent标识为python-requests/对应版本号,会被服务端识别为非人类访问的爬虫流量,直接丢弃连接不返回响应,最终表现为请求挂起、触发超时报错。另外设置的allow_redirects=False会阻断站点的合法路由跳转,5秒的超时阈值也偏短,容易受网络波动影响。
解决方法
按以下步骤调整代码即可正常下载页面内容:
- 移除
allow_redirects=False参数,允许请求跟随站点的合法3xx跳转,定位到最终的页面资源。 - 给请求添加模拟真实浏览器的请求头,核心是替换默认的
User-Agent字段,建议同步携带常规浏览器会发送的Accept、Accept-Language字段,进一步降低被拦截的概率。 - 调整超时时间到10~15秒,避免网络正常波动导致的误判超时。
- 请求发送后增加状态码校验,方便第一时间排查请求异常。
修正后可运行代码
import requests import pandas as pd from bs4 import BeautifulSoup url = "https://www.cmegroup.com/markets/energy/crude-oil/light-sweet-crude.quotes.html" # 模拟桌面端Chrome浏览器的请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Connection": "keep-alive" } response = requests.get(url, headers=headers, timeout=15) # 状态码非200时直接抛出异常,快速定位问题 response.raise_for_status() data = response.text # 后续解析逻辑可正常执行 soup = BeautifulSoup(data, "html.parser")
补充说明
如果运行代码后成功拿到HTML内容,但是解析时找不到目标行情表格,是因为CME的实时行情数据是页面加载后通过前端异步接口拉取的,静态HTML中不包含这部分动态内容。如果需要提取行情数据,可以打开浏览器开发者工具,在网络请求中筛选返回JSON格式的行情接口,直接请求接口拿结构化数据,解析效率比爬HTML页面更高。
内容的提问来源于stack exchange,提问作者dharmatech
相关产品推荐
相关产品推荐

