新手求教:如何用Scrapy向CNPQ站点发送POST请求实现指定搜索?
解决Scrapy爬取CNPQ学术站点的POST请求问题
原代码的核心问题
- 表单数据中的布尔值
True不符合HTTP表单提交规范:复选框选中时,实际提交的是字符串值(通常是"on"或特定标识),而非Python布尔类型。 - 缺少页面表单的必要隐藏字段:这类学术站点通常会包含
__VIEWSTATE、__EVENTVALIDATION等ASP.NET相关的隐藏参数,必须从页面中提取并加入POST数据,否则请求会被拒绝。 - 未明确表单提交的触发动作参数:站点表单需要特定的动作标识来执行搜索,原代码未包含该参数。
修正后的代码实现
import scrapy class LattesSpider(scrapy.Spider): name = 'lattesspider' start_urls = ['https://buscatextual.cnpq.br/buscatextual/busca.do'] def parse(self, response): # 提取页面中的ASP.NET隐藏表单字段 viewstate = response.xpath('//input[@id="__VIEWSTATE"]/@value').get() event_validation = response.xpath('//input[@id="__EVENTVALIDATION"]/@value').get() # 构造符合要求的表单数据 form_data = { '__VIEWSTATE': viewstate, '__EVENTVALIDATION': event_validation, 'filtros.buscaAssunto': 'on', # 复选框选中的正确提交值 'textoBusca': 'grafos', 'acao': 'executarBusca' # 触发搜索的动作参数 } # 发送POST请求并指定回调 yield scrapy.FormRequest( url=response.url, formdata=form_data, method='POST', callback=self.parse_profiles ) def parse_profiles(self, response): # 精准提取搜索结果中的标题与链接 for result in response.xpath('//div[contains(@class, "item-resultado")]'): yield { 'titulo': result.xpath('.//h4/a/text()').get().strip(), 'link': response.urljoin(result.xpath('.//h4/a/@href').get()) }
关键操作说明
- 提取隐藏字段:打开浏览器开发者工具(F12)查看页面源码,找到所有
input[type="hidden"]的字段,确保全部加入form_data。 - 确认复选框值:手动勾选复选框并提交搜索,在Network面板中查看POST请求的参数,找到对应复选框的键值对(比如
filtros.buscaAssunto=on)。 - 验证请求结果:在
parse_profiles中先打印response.text,确认是否返回了正确的搜索结果页面,再调整XPath提取规则。
内容的提问来源于stack exchange,提问作者aquelecaralá
相关产品推荐
相关产品推荐

