Python中如何使用Scrapy发送POST请求并传递JSON数据
需要带的数据为 data = {"a": [{"b": 'c'}]} 我用的这种写法一直不对, return scrapy.FormRequest( body=json.dumps(data), )
Python中如何使用Scrapy发送POST请求并传递JSON数据
不需要 json.loads 直接传字典试试
在Scrapy里发POST请求带JSON数据,直接用scrapy.FormRequest不太对路,得用scrapy.Request,然后把method设成'POST',body里塞JSON字符串,再配好headers里的Content-Type。
看个抓某API的完整例子:
import scrapy
import json
class MySpider(scrapy.Spider):
name = 'json_post_spider'
def start_requests(self):
# 1. 准备JSON数据
payload = {
'page': 1,
'limit': 20,
'filter': {'category': 'books'}
}
# 2. 设置请求
url = 'https://api.example.com/data'
headers = {
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0'
}
# 3. 发送POST请求
yield scrapy.Request(
url=url,
method='POST',
headers=headers,
body=json.dumps(payload), # 关键:字典转JSON字符串
callback=self.parse_response
)
def parse_response(self, response):
# 4. 处理JSON响应
try:
data = json.loads(response.text)
for item in data.get('results', []):
yield {
'title': item.get('title'),
'price': item.get('price')
}
except json.JSONDecodeError:
self.logger.error('Invalid JSON response')
几个关键点:
- body参数必须传字符串:用
json.dumps()把字典转成JSON字符串,别直接传字典 - Content-Type必须设置:
headers里一定要有'Content-Type': 'application/json',不然服务器可能不认 - 处理响应:用
json.loads()解析返回的JSON数据
如果参数是动态的,比如要翻页,可以这样:
def start_requests(self):
for page in range(1, 6):
payload = {'page': page, 'limit': 20}
yield scrapy.Request(
url='https://api.example.com/data',
method='POST',
headers={'Content-Type': 'application/json'},
body=json.dumps(payload),
meta={'page': page}, # 传递额外数据
callback=self.parse_response
)
用scrapy.Request发JSON POST就这么简单,记得配好headers和body格式就行。
总结:用Request配JSON字符串和正确的Content-Type头。
试过, 不行, formdata 传字典, 或者 body 传 json 都是 状态码 408 的错误
可以试着传一下抓包 body 的截图,如果是"?1=2&3=4"这种的话需要可能需要换个思路
数据长这个样子, b 是一个编码, 是数字和英文的
data = {“lineItems”: [{“catalogNumber”: b}]}
用 requests 写没问题, 用了 scrapy 就是 408,
试一下,request = scrapy.Request( url, method=‘POST’,
body=json.dumps(my_data),)方式
body 里是 json 字符串,headers 中加 Content-Type: application/json
还是不行
408 Request Time-out
FormRequest 中 {‘ key’: ‘ value’, ‘ k’: ‘ v’}会被转化为’key=value&k=v’ 并且默认的 method 是 POST,你可以再看一下 body 的原始格式,看是这种 key-value 的形式还是 json 格式在作分析
这个提示并不是请求格式的问题吧,自己抓自己包看看
抓包,或者写一个测试用例接受请求过来的 body 和 head,比较有什么不同,实在不行用 request 替代好了。最新的 request-html 已经自带 html 解析,满足大部分爬虫场景。
formdata=data

