You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Scrapy爬取疑问:HTTP GET响应JSON元素多于浏览器显示,如何获取过滤后数组?

解决Scrapy获取浏览器过滤后JSON数据的问题

嘿,这个场景我刚入门爬取的时候也踩过坑!浏览器显示的条目比API返回的少,核心原因几乎都是前端在拿到完整JSON后做了客户端过滤/截取,咱们一步步拆解解决:

第一步:搞清楚前端的过滤逻辑

首先得弄明白浏览器是怎么从140+条里筛出90条的,这一步靠浏览器开发者工具就能搞定:

  • 按下F12打开开发者工具,切换到「Network」标签,找到那个返回JSON的GET请求,查看「Response」面板确认完整的140+条数据确实返回了。
  • 切换到「Elements」标签,找到页面上显示数据的DOM容器,记住它的类名或ID。
  • 再切到「Sources」标签,搜索和数据处理相关的关键词(比如filterslicedisplay、你找到的DOM容器类名),找到前端处理数据的代码段。

    举个常见的例子:你可能会看到类似 const showItems = allData.filter(item => item.isVisible === true && item.date > '2024-01-01') 的代码,这就明确了过滤条件是isVisible为真且日期在2024年之后。

第二步:在Scrapy里复刻过滤逻辑

当你搞清楚前端的过滤规则后,直接在Scrapy的parse方法里实现相同的判断就行,不用再去纠结浏览器的显示:

import json
from scrapy.spiders import Spider

class MySpider(Spider):
    name = 'my_spider'
    start_urls = ['https://example.com/api/data']  # 替换成你的目标API地址

    def parse(self, response):
        # 解析完整的JSON响应
        full_data = json.loads(response.text)
        # 复刻前端的过滤条件,这里替换成你找到的规则
        filtered_data = [
            item for item in full_data
            if item.get('isVisible') is True 
            and item.get('date', '') > '2024-01-01'
        ]
        # 处理过滤后的每条数据
        for item in filtered_data:
            yield {
                'id': item.get('id'),
                'title': item.get('title'),
                'content': item.get('content')
                # 其他你需要的字段
            }

第三步:复杂场景的替代方案

如果前端的过滤逻辑特别复杂(比如涉及加密参数、动态计算的判断条件),复刻规则太麻烦,那可以用Scrapy结合浏览器渲染工具直接获取页面上已显示的数据:

  • scrapy-playwright或者scrapy-splash集成浏览器渲染,让爬虫模拟真实浏览器加载页面,然后直接从渲染后的DOM里提取显示的条目,这样就完全不用管前端的过滤逻辑了。
  • 举个scrapy-playwright的简单示例,在settings.py里配置好后,在爬虫里直接获取页面元素:
def parse(self, response):
    # 直接提取页面上显示的条目DOM
    for item_elem in response.css('.display-item-class'):  # 替换成你找到的DOM类名
        yield {
            'title': item_elem.css('.title::text').get(),
            'content': item_elem.css('.content::text').get()
        }

额外提醒

如果发现滚动页面后浏览器会加载更多数据,那可能是前端做了滚动加载,但你说的是API返回140+条却只显示90,这种情况概率较低,但也可以检查下Network里有没有后续的请求,确认是不是分页加载的问题。

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

火山引擎 最新活动