Python中如何使用scrapy-redis实现POST请求
scrapy 可以通过重写 start_requests 方法实现 post 请求,请问 scrapy-redis 如何实现
Python中如何使用scrapy-redis实现POST请求
5 回复
FormRequest 不起作用吗
在Scrapy中使用scrapy-redis实现POST请求,核心是正确配置请求的method和body参数,并确保Redis调度器和去重器正常工作。scrapy-redis本身不改变请求的构造方式,它主要负责分布式调度和去重。
下面是一个完整的Spider示例,演示如何发送POST请求:
import scrapy
import json
from scrapy_redis.spiders import RedisSpider
class MyPostSpider(RedisSpider):
name = 'post_spider'
redis_key = 'myspider:start_urls' # 从Redis列表读取起始URL或请求
def make_request_from_data(self, data):
"""
重写此方法,用于从Redis中读取的数据构造请求。
data是从redis_key列表中pop出来的字节串。
这里我们假设data是JSON格式,包含构造POST请求所需的信息。
"""
item = json.loads(data.decode('utf-8'))
# 构造FormData格式的POST请求
return scrapy.FormRequest(
url=item['url'],
formdata=item['form_data'], # 字典形式的表单数据
callback=self.parse_response
)
def parse_response(self, response):
# 处理响应
yield {
'url': response.url,
'status': response.status,
'body': response.text[:200] # 只取前200字符示例
}
# 更常见的做法:在start_requests中直接构造POST请求
class MyPostSpider2(RedisSpider):
name = 'post_spider2'
redis_key = 'myspider:start_urls'
def make_request_from_data(self, data):
"""
另一种方式:发送JSON格式的POST请求
"""
item = json.loads(data.decode('utf-8'))
return scrapy.Request(
url=item['url'],
method='POST',
body=json.dumps(item['payload']), # JSON字符串作为请求体
headers={'Content-Type': 'application/json'},
callback=self.parse_response
)
def parse_response(self, response):
yield {'result': response.json()}
# 如果你需要固定的POST请求,可以在start_requests中定义:
class MyPostSpider3(RedisSpider):
name = 'post_spider3'
def start_requests(self):
# 即使使用scrapy-redis,也可以在这里定义初始请求
yield scrapy.FormRequest(
url='https://httpbin.org/post',
formdata={'key1': 'value1', 'key2': 'value2'},
callback=self.parse
)
def parse(self, response):
yield {'form_data': response.json()['form']}
关键点:
- 请求构造:使用
scrapy.FormRequest发送表单格式的POST,或使用scrapy.Request并指定method='POST'和body参数。 - 数据格式:JSON请求需要设置
Content-Type: application/json头。 - Redis集成:
make_request_from_data方法让你可以从Redis队列中动态构造请求。 - 配置settings.py:
# 启用scrapy-redis调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
REDIS_URL = 'redis://localhost:6379/0'
# 保持Redis队列,允许暂停/恢复
SCHEDULER_PERSIST = True
向Redis队列添加任务:
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
# 添加一个POST任务
task = {
'url': 'https://httpbin.org/post',
'form_data': {'username': 'test', 'password': 'secret'}
}
r.lpush('myspider:start_urls', json.dumps(task))
总结:构造POST请求的关键在于正确使用FormRequest或Request的body参数。
data = {
‘username’: ‘user’,
‘password’: ‘pwd’
}
req = scrapy.Request(url=url, method=‘POST’,
body=data,
headers=self.headers)
楼主说的是用 scrapy-redis 时,怎么发 POST 请求,最近遇到这个问题,已经解决😊
我也解决了,开心

