【问题标题】:Translating Bash cURL commands to Python将 Bash cURL 命令翻译成 Python
【发布时间】:2023-07-18 21:40:02
【问题描述】:

我在 Bash 中有以下工作。这将如何使用 requests 或 pycurl 在 Python 中编写?

curl -o .output_data.xml -v --cert ../cert/my_cert.pem:password123 -k 'https://my.target.url' -H 'Content-Type: application/json' -d '{"document":{"header":{"exportType":"XML"}}}'

【问题讨论】:

  • 这能回答你的问题吗? Curl request to python request
  • 谢谢,但我尝试了类似这个答案的方法,但没有奏效,至少对我来说,这里的挑战是传递证书和密码组合,我无法使用 requests 开始工作跨度>
  • 我试图阅读curl 手册页来弄清楚这到底是做什么的,但它相当难以理解。密码是传递给服务器的东西,还是用于在本地解密 PEM 文件?你能找到一个可以测试的公共网站吗?
  • requests 接受 cert 参数,它似乎将 1:1 映射到上述示例。你已经能够尝试了吗? requests.get(url, cert='/path/to/pem/file')
  • github.com/psf/requests/issues/1573#issuecomment-169916326 展示了如何使用 pyCurl 执行此操作。也有 cmets 建议 requests 的解决方法,但我无法评估它们。同样,找到一个可以对其进行测试的公共网站会很有帮助。

标签: python python-requests pycurl


【解决方案1】:

感谢 Tripleee 关于 https://github.com/psf/requests/issues/1573#issuecomment-169916326 下面的 sn-p 现在可以工作了:

我只需要正确映射 cURL 选项参数:

--cert maps to c.setopt(pycurl.SSLCERT, cert_file_path) and c.setopt(pycurl.SSLKEYPASSWD, "password123")

-k maps to c.setopt(pycurl.SSL_VERIFYPEER, False)

-H maps to c.setopt(pycurl.HTTPHEADER,["Content-Type: application/json"])

-d maps to c.setopt(pycurl.POSTFIELDS, json.dumps(params)) 

-o 没有映射,所以我使用缓冲区 c.setopt(b.WRITEFUNCTION, b.write) 捕获输出。

b.getvalue() 将允许我稍后使用元素树或类似工具从捕获的 XML 字符串中解析数据。

import pycurl
import io
import json

cert_file_path = "../cert/my_cert.pem"
url = "https://my.target.url"
params={"document":{"header":{"exportType":"XML"}}}

b = io.BytesIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.SSLCERT, cert_file_path)
c.setopt(pycurl.SSLKEYPASSWD, "password123")
c.setopt(pycurl.SSL_VERIFYPEER, False)
c.setopt(pycurl.HTTPHEADER,["Content-Type: application/json"])
c.setopt(pycurl.POSTFIELDS, json.dumps(params)) 
c.setopt(c.WRITEFUNCTION, b.write)
c.perform()
xml_string = b.getvalue().decode('UTF-8')


【讨论】:

  • 感谢您使用正确的方法进行更新。请考虑添加错误和修复的摘要
  • 谢谢 - 我已经用一些解释编辑了答案
【解决方案2】:

你可以使用:

bashCommand = "curl -o .output_data.xml -L -X GET -v --cert ../cert/my_cert.pem:password123 -k 'https://my.target.url' -H 'Content-Type: application/json' -d '{"document":{"header":{"exportType":"XML"}}}'"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

【讨论】:

  • OP 要求提供有关如何使用 python requests 包或 pycurl 发出 curl 请求的解决方案。您的示例使用子进程 nad 只是通过 curl 命令。
  • 这不是一个好的解决方案,而且效率可能非常低(还依赖于正在安装的curl 工具)。我觉得requests库会更高层次,整体更好。