Scrapy自定义Cookie未生效,如何强制使用请求Cookie获取USD计价内容
问题场景与现状
本次目标为抓取hattrick.org站点球员交易历史中的USD计价交易金额,因出口访问节点位于柬埔寨地区,站点默认返回当地货币Riel的展示结果,计划通过请求携带自定义currency=USD、country=US的Cookie,强制站点返回USD计价内容。
当前已实现的逻辑与遇到的异常:
- Scrapy Settings配置:
COOKIES_ENABLED = False COOKIES_DEBUG = True - Spider核心实现逻辑:
class HtSpider(scrapy.Spider): name = 'sells' allow_domain = ['hattrick.org'] def start_requests(self): urls = ['https://www.hattrick.org'] for url in urls: player = 'goto.ashx?path=/Club/Players/Player.aspx?playerId=450940600' joint = urljoin(url, player) yield scrapy.Request( url=joint, cookies={'currency': 'USD', 'country': 'US'}, # meta={'dont_merge_cookies': True}, dont_filter=True,callback=self.price) def price(self,response): price_xpath = response.xpath('//*[@id="transferHistory"]/table//tr[1]/td[6]/text()').extract_first() print(price_xpath) # 实际输出为 2 280 000 Riel open_in_browser(response) # 本地检查页面确认确实展示Riel计价 - Cookie调试日志显示:
- 发出的请求头Cookie字段存在重复值:
Cookie: currency=USD; country=US; currency=USD; country=US; ASP.NET_SessionId=xxxxx - 站点响应仅下发
InitialOrigin相关的Set-Cookie,未对传入的币种参数做任何响应 - 最终抓取结果始终为Riel计价的金额,未达到获取USD内容的目标。
- 发出的请求头Cookie字段存在重复值:
核心原因排查
- Cookie中间件配置完全失效
将COOKIES_ENABLED设为False后,Scrapy内置的Cookie管理中间件会被完全禁用,此时所有手动传入Request对象的cookies参数不会被统一处理、拼接至请求头,也不会按照规则去重、管理Cookie优先级。日志中看到的重复Cookie值,本质是无管理状态下旧会话缓存和手动参数的叠加结果,并非你的自定义参数正常生效。
而HTTP协议本身对重复Cookie字段的处理规则是:同名字段多次出现时,服务端默认取最后一个值生效。这种重复叠加的状态下,站点基于IP地理识别返回的币种规则会直接覆盖你手动传入的USD参数。 - 站点币种校验逻辑的适配问题
hattrick.org的币种展示规则为:优先读取会话Cookie中已保存的币种值,若识别到无有效币种Cookie、或Cookie值与当前IP所属地区默认币种匹配时,会自动将币种重置为当地货币。你当前无管理的Cookie发送状态下,站点根本没有正确识别到你传入的USD币种值,自然会按默认规则返回Riel内容。 - 代码层面的提取逻辑疏漏
当前XPath中使用的"是浏览器开发者工具复制元素路径时附带的HTML转义字符,在XPath语法中无法被正确识别为双引号,即便Cookie生效,也可能存在元素定位失败的问题。
修复方案
- 调整Scrapy基础配置
将COOKIES_ENABLED改回默认的True,恢复内置Cookie中间件的正常管理能力,保留COOKIES_DEBUG = True用于调试Cookie拼接流程。 - 调整Request的Cookie处理规则
在内置Cookie中间件启用后,通过meta参数控制Cookie的合并逻辑:- 明确跳过服务端基于地理位置下发的币种类Cookie,避免其覆盖你手动指定的USD、US参数;如果需要完全避免服务端下发的Cookie篡改你的自定义参数,可打开注释的
meta={'dont_merge_cookies': True}配置,注意需要保留会话必需的Cookie(如ASP.NET_SessionId),否则站点可能拒绝返回有效页面 - 确保手动传入的
currency=USD、country=US参数在Cookie字段中无重复,且位于Cookie字段的优先级生效位置
- 明确跳过服务端基于地理位置下发的币种类Cookie,避免其覆盖你手动指定的USD、US参数;如果需要完全避免服务端下发的Cookie篡改你的自定义参数,可打开注释的
- 修正元素提取逻辑
将XPath中的转义字符替换为标准双引号:price_xpath = response.xpath('//*[@id="transferHistory"]/table//tr[1]/td[6]/text()').extract_first() - 验证环节
开启调试后检查最终发出的请求头Cookie,确认currency=USD无被其他同名字段覆盖,再校验返回页面的金额单位是否为USD。
内容的提问来源于stack exchange,提问作者crianopa
相关产品推荐
相关产品推荐

