You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用Scrapy抓取XHR接口无返回数据排查求助

问题排查与解决方案

核心问题点

  • 请求地址错误:当前代码请求的是基金价格的前端展示页面,返回内容为HTML格式,并非你需要的XHR接口JSON数据,直接调用json.loads会抛出解析异常,导致没有预期输出。
  • 硬编码临时Cookie:代码中写死的Cookie是你本地浏览器的临时会话数据,存在有效期,过期后请求会被网站拒绝,无法拿到正确返回。
  • 缺少调试逻辑:没有先验证返回内容的格式,直接做JSON解析,无法定位是请求失败还是数据格式不符的问题。

修复步骤

  1. 先从浏览器开发者工具的「网络」面板筛选XHR请求,找到真实返回基金价格数据的接口地址,替换代码中的请求URL。
  2. 取消硬编码Cookie,让Scrapy自动管理会话Cookie:先请求一次前端页面拿到有效会话凭证,再携带凭证请求数据接口。
  3. 增加调试逻辑,先打印返回内容确认格式正确后再做JSON解析。

修复后的代码示例

import scrapy
import json
from scrapy.http import HtmlResponse

class PublicMutual(scrapy.Spider):
    name = 'publicmutual'
    base_headers = {
        'Accept': '*/*',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9',
        'Connection': 'keep-alive',
        'Referer': 'https://www.publicmutual.com.my/Our-Products/UT-Fund-Prices',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }

    def start_requests(self):
        # 先请求前端页面,获取有效Cookie和动态校验token
        yield scrapy.Request(
            url='https://www.publicmutual.com.my/Our-Products/UT-Fund-Prices',
            headers=self.base_headers,
            callback=self.parse_page
        )

    def parse_page(self, response: HtmlResponse):
        # 提取页面中的动态__RequestVerificationToken,不要硬编码
        verify_token = response.xpath('//input[@name="__RequestVerificationToken"]/@value').get()
        # 替换成你从浏览器中找到的真实XHR数据接口地址
        api_url = '替换为真实的XHR接口地址'
        # 构造接口请求,Scrapy会自动携带之前拿到的Cookie
        yield scrapy.Request(
            url=api_url,
            headers={**self.base_headers, '__RequestVerificationToken': verify_token},
            callback=self.parse_api
        )

    def parse_api(self, response):
        # 先打印返回内容确认格式
        print("返回内容预览:", response.text[:500])
        try:
            data = json.loads(response.body)
            print("解析后的JSON数据:", data)
        except json.JSONDecodeError as e:
            print("JSON解析失败,错误信息:", e)

额外注意事项

  • 部分接口可能需要携带查询参数,比如基金类型、日期、分页参数等,需要和浏览器中发起的请求参数保持一致。
  • 运行爬虫时可以添加参数scrapy crawl publicmutual -s LOG_LEVEL=DEBUG查看完整请求日志,方便定位问题。

内容的提问来源于stack exchange,提问作者user1897151

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:27:05