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

如何用Python的Scrapy爬取无URL变化的动态分页表格

解决动态分页(URL不变)的表格爬取问题

目标网站的表格采用AJAX动态加载分页,切换页码时URL不会改变,原Scrapy爬虫通过提取分页链接发起普通GET请求的方式无法获取下一页数据——因为分页数据并非通过页面跳转加载,而是通过后台接口异步返回HTML片段更新页面。

问题分析

原代码中尝试提取的ul.pager__list li.pager__page a.page-link.solr-ajaxified的href,实际是触发AJAX请求的触发链接,并非可直接访问的页面URL。点击分页按钮时,浏览器会发送POST请求到特定接口,携带分页参数(如页码、每页条数),接口返回表格的HTML片段用于更新页面。

解决步骤

  1. 抓包分析AJAX接口:

    • 打开浏览器开发者工具(F12),切换到Network标签页,筛选XHR类型请求。
    • 点击下一页按钮,观察请求的URL、请求方法(POST)、Form Data参数(比如page、rows、facet等)。
    • 记录接口地址及所需参数(示例接口:https://www.inesss.qc.ca/thematiques/medicaments/medicaments-evaluation-aux-fins-dinscription.html/jfmulticontent_c767-6/ajax)。
  2. 修改Scrapy爬虫:

    • 直接向AJAX接口发送POST请求,携带分页参数。
    • 处理接口返回的HTML片段,提取表格数据。
    • 递增页码参数,循环请求直到接口返回空数据。

修改后的代码示例

import scrapy
from scrapy.http import FormRequest

class InesssspiderSpider(scrapy.Spider):
    name = "inesssspider"
    allowed_domains = ["www.inesss.qc.ca"]
    ajax_url = "https://www.inesss.qc.ca/thematiques/medicaments/medicaments-evaluation-aux-fins-dinscription.html/jfmulticontent_c767-6/ajax"
    current_page = 0
    rows_per_page = 10

    def start_requests(self):
        yield FormRequest(
            url=self.ajax_url,
            formdata={
                'page': str(self.current_page),
                'rows': str(self.rows_per_page),
                'sort': 'date_desc',
                'facet': 'true'
            },
            callback=self.parse_ajax_response
        )

    def parse_ajax_response(self, response):
        table_rows = response.css('tr.even, tr.odd')
        if not table_rows:
            return
        
        for table_row in table_rows:
            yield {
                'DATE': table_row.css('td:nth-child(1)::text').get(default='').strip(),
                'Nomcommercial/Projet': table_row.css('td:nth-child(2) a::text, td:nth-child(2)::text').get(default='').strip(),
                'Dénominationcommune/Sujet': table_row.css('td:nth-child(3) a::text, td:nth-child(3)::text').get(default='').strip(),
                'Fabricant': table_row.css('td:nth-child(4)::text').get(default='').strip(),
                'RecommandationINESSS': table_row.css('td:nth-child(5)::text').get(default='').strip(),
                'DécisionMinistre': table_row.css('td:nth-child(6)::text').get(default='').strip(),
            }
        
        self.current_page += 1
        yield FormRequest(
            url=self.ajax_url,
            formdata={
                'page': str(self.current_page),
                'rows': str(self.rows_per_page),
                'sort': 'date_desc',
                'facet': 'true'
            },
            callback=self.parse_ajax_response
        )

关键注意事项

  • 请求参数准确性:所有Form Data参数必须和抓包结果完全一致,包括参数名和值的格式,否则接口可能返回错误或空数据。
  • 请求头模拟:如果接口验证请求头,需在FormRequest中添加headers参数,模拟浏览器的User-Agent、Referer等信息。
  • 终止条件:当接口返回的表格行为空时停止请求,避免无限循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:47:02