【问题标题】:How to execute Curl in Python如何在 Python 中执行 Curl
【发布时间】:2018-02-25 01:31:22
【问题描述】:

我正在尝试在 python 脚本中执行 curl 命令,但无法通过符号传递密码。

import os;
os.system("curl -H 'Content-Type: text/xml;charset=UTF-8' -u 'appuser:appuser!@3pass' -i -v 'http://app.com/webservice/getUserData' -o userdata.xml")

我收到拒绝访问消息作为回报,用户名和密码是正确的。我想这是因为密码中的特殊字符。 我试过转义 appuser\!\@3pass 这样的字符,但没有帮助。

谁能指导一下?

【问题讨论】:

  • 1.始终使用 subprocess.Popen 而不是 os.system 等,2. 当 libcurl 绑定存在时,不要使用单独的进程。
  • 2.永远不要用分号结束你的行:)
  • 你运行的是windows还是linux? (注意:密码中没有任何特殊字符)
  • 我使用的是 Windows 7

标签: python windows curl


【解决方案1】:

您正在使用的命令无法工作,因为单引号在 Windows 中没有特殊含义,它们按字面意思传递给 curl 程序。因此,如果您从 Linux 复制了命令行(它可以工作),这将无法在这里工作(虚假引号被传递给 curl,例如用于接收 'appuserappuser!@3pass' 的登录/密码字段,也Content-Type: text/xml;charset=UTF-8 根本不受保护,被理解为 2 个单独的参数)

从控制台进行简单测试:

K:\progs\cli>curl.exe -V
curl 7.50.3 (x86_64-pc-win32) libcurl/7.50.3 OpenSSL/1.0.2h nghttp2/1.14.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smb smbs smtp smtps
telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM SSL HTTP2

(如果我使用带有双引号的 "-V" 也可以),但是如果我在版本 arg 上使用简单的引用,我会得到:

K:\progs\cli>curl.exe '-V'
curl: (6) Could not resolve host: '-V'

正如 o11c 所说,有一个 python 模块来处理 curl,你最好用它。

对于其他无法做到的情况,不推荐使用os.system。例如使用subprocess.check_call 更好(python 3.5 有一个统一的run 函数):

  • 检查返回代码,如果出错则引发异常
  • 无需手动操作即可传递和引用参数。

让我们修正你的例子:

subprocess.check_call(["curl","-H","Content-Type: text/xml;charset=UTF-8","-u",'appuser:appuser!@3pass',"-i","-v",'http://app.com/webservice/getUserData',"-o","userdata.xml"])

请注意,我故意混合使用单引号和双引号。 Python 不在乎。如果参数中有空格,check_call 机制会自动处理参数保护/引用。

调用此脚本时,我得到userdata.xml 填写如下:

HTTP/1.1 301 Moved Permanently
Date: Fri, 15 Sep 2017 20:49:50 GMT
Server: Apache
Location: http://www.app.com/webservice/getUserData
Content-Type: text/html; charset=iso-8859-1
Transfer-Encoding: chunked

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.app.com/webservice/getUserData">here</a>.</p>
</body></html>

【讨论】:

  • 在 Windows 上,args 列表通过subprocess.list2cmdline 转换为命令行字符串,这假定应用程序将遵循VC++CommandLineToArgvW 通用的解析规则。 curl.exe 可能遵循这些规则。大多数应用程序都这样做。 IIRC,一些 Cygwin 可执行文件使用不同的规则。
  • @eryksun 我不确定。实际上我读到 list2cmdline 只模拟了命令发送到系统的方式,但你不能依赖它。不过,您对 execv 是正确的。我会编辑它
  • @eryksun 我很幸运能在我的电脑上安装一个 curl 版本。我测试了简单的引号,它们按字面意思传递。 curl 无法将它们剥离。
  • 这里:stackoverflow.com/questions/14836947/… 一个答案暗示 list2cmdline “尽其所能”。
  • 某些应用程序如 schtasks.exe 实际上对 both 单引号和双引号都有特殊的解析。我的第一条评论只是为了澄清 Popen 为 args 列表所做的事情。它是否适用于 curl.exe 是您所做的实验问题,或者在调试器下运行它以检查它是否使用来自 Microsoft 的 CRT、CommandLineToArgvWargv 数组或一些自定义命令 -行解析。缺乏一致性是不幸的,但那是 Windows...
猜你喜欢
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
相关资源
最近更新 更多