scrapy中提交表单或json数据需用formrequest或request/jsonrequest构造post请求,确保编码格式匹配;formdata键值须为str类型,jsonrequest的data须为字典;cookies和headers需按规范传入。

要在Scrapy中向目标接口准确提交表单或JSON数据并获取响应,必须绕过默认的GET请求机制,手动构造POST请求对象并确保编码格式与服务端预期严格一致,否则服务器将返回400、空响应或跳转到登录页。
用FormRequest发表单类POST(最常用)
适用于登录页、搜索框、筛选条件等HTML表单场景,数据自动按application/x-www-form-urlencoded编码,无需手动处理键值对拼接。
第一步:在爬虫类中注释或删除start_urls,避免父类自动发起GET请求;
第二步:重写start_requests(self)方法,在其中使用yield scrapy.FormRequest();
第三步:传入url(必填)、formdata(字典,键名必须与网页源码中input标签的name属性完全一致)、callback(响应处理函数);
这一步操作起来很简单,直接把文件拖进去就行。但注意:【formdata字典里的所有键和字符串值都必须是str类型,数字如"1"不能写成1,否则会报TypeError】;
第四步:在回调函数中用response.text或json.loads(response.body)解析返回内容。
用Request发JSON类POST(API接口专用)
当目标URL是RESTful API、需提交JSON体、或服务端明确要求Content-Type: application/json时,必须用scrapy.Request并手动设置请求体和头。
方法一:手动序列化+设headers
在start_requests中写:yield scrapy.Request(url=url, method="POST", body=json.dumps(payload), headers={"Content-Type": "application/json"}, callback=self.parse);
方法二:用JsonRequest(Scrapy 2.2+内置,更简洁)
直接yield scrapy.http.JsonRequest(url=url, data=payload, callback=self.parse),它自动序列化data并设置好Content-Type,不用再写json.dumps和headers;
注意:【JsonRequest的data参数接收原生Python字典,不是字符串;若误传字符串会抛出TypeError】。
携带Cookies或User-Agent等额外参数
很多POST接口要求带登录态或伪装浏览器,这时需在请求对象中加入cookies或headers参数。
如果cookies来自外部(比如Selenium登录后导出),必须构造成Python字典格式,例如{"sessionid": "abc123", "csrftoken": "xyz789"};
设置User-Agent推荐使用custom_settings全局配置,避免每个请求重复写;若仅个别请求需要特殊UA,则在headers里单独指定"User-Agent"字段;
这一步容易踩坑:headers里的键名必须用字符串,且Content-Type不能和formdata混用——用了formdata就别再手动设Content-Type,否则FormRequest会冲突报错。











