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

Scrapy爬取分页URL不变的站点多页数据实现方案

问题根因

目标站点是ASP.NET WebForm架构,分页切换不会修改URL,通过提交页面内置的隐藏表单字段(__VIEWSTATE、__VIEWSTATEGENERATOR、__EVENTVALIDATION)发POST请求实现分页,直接GET固定URL只能拿到第一页数据。

实现方案
  • 首次GET请求拿到第一页内容后,先提取当前页所有律师详情链接,交给详情解析函数处理
  • 从第一页的分页栏提取总页码,确定翻页终止条件
  • 每一页处理完后,提取当前页所有隐藏表单字段,补充分页触发参数,构造POST请求请求下一页
  • 逐页递推直到到达最后一页,即可拿到全量数据
  • 原配置的单域名并发1、1秒请求延迟刚好适配该场景,ASP.NET的隐藏参数和页序强绑定,乱序并发会导致参数失效
修改后可直接运行的代码
import scrapy
from scrapy.http import Request, FormRequest


class TestSpider(scrapy.Spider):
    name = 'test'
    start_urls = ['https://www.ifep.ro/justice/lawyers/lawyerspanel.aspx']
    custom_settings = {
        'CONCURRENT_REQUESTS_PER_DOMAIN': 1,
        'DOWNLOAD_DELAY': 1,
        'USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }

    def parse(self, response, current_page=1, total_page=None):
        # 提取当前页所有律师详情页链接
        lawyer_links = response.xpath("//div[@class='list-group']//@href").extract()
        for link in lawyer_links:
            url = response.urljoin(link)
            if url.endswith('.ro') or url.endswith('.ro/'):
                continue
            yield Request(url, callback=self.parse_book)

        # 第一页加载时计算总页数
        if total_page is None:
            page_nums = []
            for page_text in response.xpath("//div[contains(@class,'pager')]//a/text()").getall():
                page_text = page_text.strip()
                if page_text.isdigit():
                    page_nums.append(int(page_text))
            total_page = max(page_nums) if page_nums else 1

        # 构造下一页请求
        if current_page < total_page:
            next_page = current_page + 1
            # 收集当前页所有隐藏表单参数
            formdata = {}
            for hidden in response.xpath("//input[@type='hidden']"):
                name = hidden.xpath("./@name").get()
                value = hidden.xpath("./@value").get("")
                if name:
                    formdata[name] = value
            # 补充分页触发参数
            formdata["__EVENTTARGET"] = "AspNetPager1"
            formdata["__EVENTARGUMENT"] = str(next_page)
            
            yield FormRequest(
                url=response.url,
                formdata=formdata,
                callback=self.parse,
                cb_kwargs={"current_page": next_page, "total_page": total_page}
            )

    def parse_book(self, response):
        title = response.xpath("//span[@id='HeadingContent_lblTitle']//text()").get()
        d1 = response.xpath("//div[@class='col-md-10']//p[1]//text()").get()
        d1 = d1.strip() if d1 else ""
        d2 = response.xpath("//div[@class='col-md-10']//p[2]//text()").get()
        d2 = d2.strip() if d2 else ""
        d3 = response.xpath("//div[@class='col-md-10']//p[3]//span//text()").get()
        d3 = d3.strip() if d3 else ""
        d4 = response.xpath("//div[@class='col-md-10']//p[4]//text()").get()
        d4 = d4.strip() if d4 else ""

        yield {
            "title1": title,
            "title2": d1,
            "title3": d2,
            "title4": d3,
            "title5": d4,
        }
排错提示
  • 如果分页请求返回错误,打开浏览器F12网络面板,手动点击一次分页,查看POST请求体里的__EVENTTARGET实际值,替换代码中对应字符串即可
  • 代码新增了字段非空判断,避免个别律师详情页字段缺失导致爬虫中断
  • 不要随意调高并发数、调低延迟,否则大概率触发站点反爬或者参数校验失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:15:35