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

Scrapy框架如何检测并爬取带无限滚动机制的网页

无限滚动页面爬取方案

Scrapy默认仅发起初始HTTP请求、不执行页面JS,而无限滚动的实现逻辑是:用户滚动到页面底部时,前端自动发起异步请求拉取下一批内容追加到当前页,因此初始请求拿到的HTML仅包含首屏数据,自然会出现数据不全的问题。

优先用接口直连方案(效率最高,不依赖浏览器渲染)

1. 定位动态加载接口

不要上来就接Selenium/Playwright这类重渲染工具,先按以下步骤抓接口,效率比重方案高几十倍:

  • 打开目标页面,按F12调出开发者工具,切换到「网络」面板,勾选Fetch/XHR过滤规则
  • 清空现有请求记录,手动滚动页面到底部触发新内容加载
  • 观察新增的请求,这类接口一般带page、offset、cursor、start这类分页参数,返回结果要么是结构化JSON,要么是待插入页面的HTML片段
  • 手动修改分页参数发起请求,验证是否能直接拿到对应页内容,不需要额外签名、cookie校验的话,直接在Scrapy里构造请求爬取即可。

2. 改造现有爬虫代码

原有CrawlSpider的规则不需要全部推翻,只需要针对存在无限滚动的页面单独加分页递推逻辑即可,参考改法:

import re
from scrapy import Request
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from w3lib.url import url_query_cleaner, add_or_replace_parameter


def process_links(links):
    for link in links:
        link.url = url_query_cleaner(link.url)
        yield link


class myCrawler(CrawlSpider):
    name = 'symphony'
    allowed_domains = ['theshell.org']
    start_urls = ['https://www.theshell.org/']
    base_url = 'https://www.theshell.org/'

    custom_settings = {
        'DOWNLOADER_MIDDLEWARES': {'sitescrapper.middlewares.RotateUserAgentMiddleware': 400, },
        'COOKIES_ENABLED': False,
        'CONCURRENT_REQUESTS': 6,
        'DOWNLOAD_DELAY': 1,
        'ITEM_PIPELINES': {'sitescrapper.pipelines.DuplicatesPipeline': 300},
        'FEEDS': {'csv_file.csv': {'format': 'csv'}}
    }

    rules = (
        Rule(
            LinkExtractor(allow_domains='theshell.org',
                            deny=[r'calendar'],
                        ),
            process_links=process_links,
            callback='parse_item',
            follow=True
        ),
    )

    def parse_infinite_scroll(self, response):
        # 解析当前页内容,和普通页逻辑一致
        yield {
            'url': response.url,
            'html_data': response.text
        }
        # 递推构造下一页请求,以下逻辑需替换为你抓包拿到的实际接口规则
        current_page = response.meta.get('page', 1)
        next_page = current_page + 1
        # 终止条件:当前页无有效内容时停止递推,选择器替换成实际的内容节点选择器
        if len(response.xpath('//div[@class="list-item"]')) > 0:
            next_url = add_or_replace_parameter(response.url, 'page', next_page)
            yield Request(
                url=next_url,
                callback=self.parse_infinite_scroll,
                meta={'page': next_page}
            )

    def parse_item(self, response):
        # 匹配无限滚动类页面的路径规则,交给专门的解析逻辑
        if re.match(r'https://www.theshell.org/.*/list/.*', response.url):
            yield from self.parse_infinite_scroll(response)
            return
        # 普通页面走原有解析逻辑
        yield {
            'url': response.url,
            'html_data':response.text
        }

注意:代码里的分页参数规则、内容判空选择器、无限滚动页面的路径匹配规则,都要替换成目标站点实际的逻辑,不要直接照搬。

接口加密场景的备选方案

如果抓到的接口有动态签名、必须执行JS才能生成合法请求参数,再接入scrapy-playwright做页面渲染:

  1. 安装依赖:执行pip install scrapy-playwright && playwright install chromium
  2. 在配置中开启playwright下载器中间件,对需要处理无限滚动的页面传入Playwright页面对象,注入JS脚本自动滚动到底部,直到页面高度不再变化(即无新内容加载),再返回完整渲染后的页面内容给解析函数。
    该方案请求速度远低于接口直连,仅适合接口加密无法破解的场景。

无限滚动页面的判断标准

  • 初始返回的HTML中列表内容仅展示前10-20条,页面底部无传统分页按钮(如下一页、页码跳转控件)
  • 滚动到底部时会出现加载动画,同时网络面板出现新的XHR/Fetch请求
  • 页面源码中可监听到scroll事件绑定的加载逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:39:24