将curl执行的POST请求转换为基于requests模块的Python请求

3 投票
1 回答
1056 浏览
提问于 2025-04-17 16:40

我需要在运行爬虫的时候把一个扩展设置发送给scrapy。用curl命令来做这件事其实很简单:

 http://localhost:6800/schedule.json -d project=myproject -d spider=somespider -d setting=DOWNLOAD_DELAY=2 -d arg1=val1

但是当我想把这个放到一个基于requests模块的Python脚本里时,我对设置=DOWNLOAD_DELAY=2有点困惑,因为它的格式跟通常的(键=值)不太一样。

所以我试了这个:

r = requests.post("http://httpbin.org/get", params={'arg1': 'val1', 'setting=DOWNLOAD_DELAY': '2'})

但是对scrapy的正常行为没有任何影响。

提前谢谢大家。

1 个回答

4

通常,在命令行中传递的键值对里,你应该在第一个=符号处分开,而不是第二个。所以,应该这样做:

r = requests.post("http://httpbin.org/get", params={'arg1': 'val1', 'setting': 'DOWNLOAD_DELAY=2'})

比如,在GNU的文档中提到的程序参数语法规范里:

长选项由‘--’开头,后面跟着由字母、数字和短横线组成的名称。选项名称通常由一到三个单词组成,单词之间用短横线分隔。用户可以缩写选项名称,只要缩写是唯一的。

要为长选项指定一个参数,可以写成‘--name=value’。这种写法允许长选项接受一个可选的参数。

换句话说,在--foo=bar=baz中,foo是名称,而bar=baz是值,因为=后面的部分不是字母、数字或短横线。

同样,curl处理选项-d foo=bar=baz时,foo是名称,bar=baz是值。

你不能直接从任何规范中推断出这一点——实际上,你甚至不能直接推断出curl遵循GNU的参数语法,因为它不是GNU程序,并且(如果我没记错的话)它有自己独特的参数解析方式。所以,你需要查看源代码才能完全确定。

或者,更简单的方法是测试一下。捕获curl发送的表单编码请求。(如果你不知道怎么做:可以尝试用netcat运行一个假服务器,比如在Mac/BSD系统上运行nc -kl 8888,然后执行curl http://localhost:8888/schedule.json -d project=myproject -d spider=somespider -d setting=DOWNLOAD_DELAY=2 -d arg1=val1,看看命令行上显示了什么。)

不过,这种行为几乎在任何有name=value对的地方都是一种隐含的标准。

撰写回答