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

Scrapy爬取API遇JSON解码错误:无法解析merolagani接口响应

问题解决与代码优化方案

问题原因分析

  1. API URL构造错误:你直接将参数拼在接口路径后,缺少?分隔符,导致服务器无法识别请求参数,返回非JSON格式的错误响应。
  2. 硬编码Cookies过期:ASP.NET_SessionId是会话临时凭证,硬编码的旧值已失效,服务器返回权限验证相关的HTML页面而非目标JSON数据。

解决步骤

  1. 修正API URL的参数拼接方式,添加?分隔路径与参数
  2. 先请求目标页面动态获取有效Cookies,再发起API请求
  3. 使用Scrapy内置的response.json()方法解析响应,避免手动处理编码问题

优化后的代码

import scrapy
from urllib.parse import urlencode
from liveshare.items import AGMSpiderItems


class SubIndexSpider(scrapy.Spider):
    name = "subindexes"
    BASE_URL = "https://merolagani.com"
    MARKET_SUMMARY_PAGE = f"{BASE_URL}/MarketSummary.aspx"
    API_ENDPOINT = f"{BASE_URL}/handlers/webrequesthandler.ashx"

    def start_requests(self):
        # 先请求页面获取服务器颁发的有效Cookies
        yield scrapy.Request(
            url=self.MARKET_SUMMARY_PAGE,
            callback=self.fetch_api_data,
            dont_filter=True
        )

    def fetch_api_data(self, response):
        # Scrapy会自动维护CookieJar,无需手动传递Cookies
        headers = {
            'accept': 'application/json, text/javascript, */*; q=0.01',
            'referer': self.MARKET_SUMMARY_PAGE,
            'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
            'x-requested-with': 'XMLHttpRequest',
        }
        params = {'type': 'market_summary'}
        api_url = f"{self.API_ENDPOINT}?{urlencode(params)}"
        
        yield scrapy.Request(
            url=api_url,
            headers=headers,
            callback=self.parse_response,
            dont_filter=True
        )

    def parse_response(self, response):
        try:
            json_data = response.json()
            self.logger.info("JSON解析成功")
            
            # 此处添加数据处理逻辑,例如生成Item
            # for sub_index in json_data.get('SubIndexes', []):
            #     yield AGMSpiderItems(**sub_index)
                
        except ValueError as e:
            self.logger.error(f"JSON解析失败: {str(e)}")
            # 打印响应前500字符用于排查问题
            self.logger.error(f"响应内容预览: {response.text[:500]}")

代码优化点说明

  • 动态Cookies管理:通过先请求页面让Scrapy自动维护CookieJar,彻底避免硬编码过期凭证的问题
  • 简化请求头:移除不必要的字段(如sec-ch-ua系列、cache-control等),只保留接口要求的核心字段
  • 内置JSON解析:使用response.json()替代json.loads(response.body),自动处理编码、BOM头等边缘情况
  • 常量提取:将固定URL提取为类常量,提升代码可维护性
  • 错误日志增强:捕获解析异常并打印响应预览,便于快速定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:17