Scrapy爬取mphc.gov.in提交数据后返回空结果求助
解决Scrapy提交表单后返回空数据的问题
看起来你在爬取Madhya Pradesh高等法院判决页面时,遇到了提交搜索参数后返回空列表的问题。我帮你梳理下代码里的几个关键问题,然后给出修正后的完整方案:
问题根源分析
你的代码存在几个核心问题,导致无法正确触发搜索并获取结果:
- 未正确提交表单数据:你只是再次发起了GET请求到首页,完全没有传递搜索所需的POST参数和请求头——相当于你打开了页面,但根本没点击搜索按钮。
- 参数名错误:Free-Text输入框对应的表单字段名是
txt_free,但你把搜索关键词“A”放到了btn_search参数里,这就导致网站根本没收到你的搜索关键词。 - 硬编码csrf_token:网站的CSRF令牌是动态生成的,硬编码的值很快会失效,必须从当前页面中实时提取。
- 请求方法错误:搜索操作需要用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
相关产品推荐
相关产品推荐

