如何用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片段用于更新页面。
解决步骤
抓包分析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)。
修改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
相关产品推荐
相关产品推荐

