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

Scrapy爬取mphc.gov.in提交数据后返回空结果求助

解决Scrapy提交表单后返回空数据的问题

看起来你在爬取Madhya Pradesh高等法院判决页面时,遇到了提交搜索参数后返回空列表的问题。我帮你梳理下代码里的几个关键问题,然后给出修正后的完整方案:

问题根源分析

你的代码存在几个核心问题,导致无法正确触发搜索并获取结果:

  1. 未正确提交表单数据:你只是再次发起了GET请求到首页,完全没有传递搜索所需的POST参数和请求头——相当于你打开了页面,但根本没点击搜索按钮。
  2. 参数名错误:Free-Text输入框对应的表单字段名是txt_free,但你把搜索关键词“A”放到了btn_search参数里,这就导致网站根本没收到你的搜索关键词。
  3. 硬编码csrf_token:网站的CSRF令牌是动态生成的,硬编码的值很快会失效,必须从当前页面中实时提取。
  4. 请求方法错误:搜索操作需要用POST请求提交表单,你用了默认的GET方法,无法传递表单数据。

修正后的完整代码

import scrapy
from scrapy import Request
from scrapy.utils.response import open_in_browser

class MphcSpider(scrapy.Spider):
    name = 'mphc'
    start_urls = ['https://mphc.gov.in/judgement-orders']

    def start_requests(self):
        yield scrapy.Request(
            self.start_urls[0],
            callback=self.parse,
            errback=self.errback_httpbin,
            dont_filter=True
        )

    def parse(self, response):
        # 从页面中动态提取最新的CSRF令牌
        csrf_token = response.css('input[name="csrf_token"]::attr(value)').get()
        if not csrf_token:
            self.logger.error("Failed to fetch CSRF token from page")
            return

        # 构造模拟浏览器的请求头,添加Referer避免被拦截
        headers = {
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'en-US,en;q=0.9',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest',
            'Connection': 'keep-alive',
            'Referer': self.start_urls[0]
        }

        # 正确的表单参数,注意字段名和值的对应关系
        form_data = {
            'txt_free': 'A',  # Free-Text输入框的内容
            'btn_search': 'Search',  # 搜索按钮的提交值
            'ddl_o_j_fo': '',
            'fno': '01',
            'txt_order_dt': '',
            'j1': '',
            'j2': '',
            'pj': '',
            'ct': '',
            'cn': '',
            'cy': '',
            'id': 'IND',
            'page': '1',
            'sort': 'jo',
            'ad': 'DESC',
            'date1': '19-06-2020',
            'date2': '19-06-2020',
            'code': '',
            'csrf_token': csrf_token,  # 使用动态提取的令牌
        }

        # 发起POST请求提交表单
        yield Request(
            self.start_urls[0],
            callback=self.start_scraping,
            method='POST',
            formdata=form_data,  # Scrapy自动处理表单编码和Content-Type头
            headers=headers,
            dont_filter=True
        )

    def start_scraping(self, response):
        open_in_browser(response)
        # 提取数据时直接获取文本内容,避免拿到整个HTML标签
        total_cases = response.css('.bbb b::text').getall()
        case_numbers = response.css('#dv_srh_dt a::text').getall()
        bench_info = response.css('#bench+ table b:nth-child(1)::text').getall()

        print(f"Total cases found: {total_cases}")
        print("-------------------------------------")
        print(f"Case numbers: {case_numbers}")
        print(f"Bench information: {bench_info}")

    def errback_httpbin(self, failure):
        self.logger.error(f"Request failed: {repr(failure)}")

关键修正细节

  • 动态获取CSRF令牌:从页面的隐藏输入框中提取实时有效的令牌,避免硬编码导致的验证失败。
  • 修正参数名:把搜索关键词放到正确的txt_free字段,btn_search设置为按钮的实际提交值“Search”。
  • 使用POST请求:明确指定请求方法为POST,并用formdata参数传递表单数据,Scrapy会自动处理表单编码和对应的请求头。
  • 添加Referer头:模拟浏览器的请求来源,降低被网站反爬机制拦截的概率。
  • 优化选择器:用::text直接提取文本内容,而不是整个HTML节点,这样得到的是干净的目标数据,而非标签字符串。

这样修改后,你的代码应该能正确提交搜索请求,并获取到2020年6月19日包含“A”的判决数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:12:54