如何在Python中记录curl的响应?
import os
os.system("curl --head http://somewebsite.com")
这段代码会输出:
HTTP/1.1 200 OK
Server: MochiWeb/1.0
Date: Fri, 22 Aug 2014 22:24:54 GMT
Content-Type: application/json
Cache-Control: no-cache
Access-Control-Allow-Origin: *
这个链接返回的是以JSON格式流式传输的数据,我该如何在Python中记录这个响应呢?
1 个回答
你不应该这样做。稍后我会解释原因;首先我会告诉你怎么让它工作。你有三个问题,需要全部解决。
正如curl
的手册上所说:
-I, --head
(HTTP/FTP/FILE) 只获取HTTP头信息!HTTP服务器有一个HEAD命令,curl用它来只获取文档的头部信息。当在FTP或文件上使用时,curl只会显示文件大小和最后修改时间。
所以你是在明确告诉curl不要发送响应的主体内容。要解决这个问题,不要发送--head
。
os.system("curl http://somewebsite.com")
根据os.system
的文档:
在Unix系统上,返回值是进程的退出状态,格式与
wait()
指定的格式一致……在Windows上,返回值是系统命令行执行command后返回的值。
换句话说,你得到的只是一个退出代码——一个小整数。输出只是被打印出来;你无法记录它。要真正记录文本,可以看看下一段:
subprocess
模块提供了更强大的功能来启动新进程并获取它们的结果;使用这个模块比使用这个函数更好。请查看subprocess
文档中的用subprocess
模块替换旧函数部分,里面有一些有用的示例。
跟着那个链接,你会看到如何在第一个例子中获取输出:使用check_output
函数。注意你需要把命令行转换成参数列表。(你可以使用shell=True
,但没有必要;在这里,shell只会给你添麻烦。)
output = subprocess.check_output(["curl", "http://somewebsite.com"])
最后,默认情况下,curl
会把主体输出到标准输出(stdout)——这很好,因为你就是要捕获这个内容——但它也会把一些信息输出到标准错误(stderr),这可能包括进度条、头部信息等,具体取决于不同情况。除非你想捕获这些信息,或者只是想让用户看到这些信息,否则你需要告诉curl不要这样做。有关详细信息,请查看上面链接的手册:
output = subprocess.check_output(["curl", "-q", "http://somewebsite.com"])
所以,这样做是可行的。那为什么不想这样做呢?
因为有一种更好的方法来实现你想要的:urllib.request
模块(如果你使用的是Python 2.x,则是urllib2
):
output = urllib.request.urlopen('http://www.somewebsite.com').read()
这有什么好处呢?
- 可移植:在任何可以运行Python的系统上都能工作,而不仅仅是安装了
curl
的系统。 - 更简单:不需要搞清楚外部程序的正确参数,然后再想办法从Python传递它们。
- 更好的错误处理:你可以检查HTTP状态码,而不是试图解析
curl
给你的任何东西。 - 更灵活:如果你想分别获取头部和数据,可以单独获取,而不需要搞清楚如何让curl把头部输出到一个单独的管道,然后从Python中用
Popen
读取两个管道而不发生死锁。 - 更容易调试。