在Python中使用HTTP GET的最快方法是什么?

Fra*_*ger 589 python networking http

如果我知道内容将是一个字符串,那么在Python中使用HTTP GET的最快方法是什么?我正在搜索文档中的快速单行,如:

contents = url.get("http://example.com/foo/bar")
Run Code Online (Sandbox Code Playgroud)

但是,所有我能找到使用谷歌是httpliburllib-我无法找到这些库中的快捷方式.

标准Python 2.5是否具有上述某种形式的快捷方式,还是应该编写函数url_get

  1. 我宁愿不把shell的输出捕获到wgetcurl.

Nic*_*sta 847

Python 2.x:

import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()
Run Code Online (Sandbox Code Playgroud)

Python 3.x:

import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()
Run Code Online (Sandbox Code Playgroud)

urllib.request的文档和阅读.

那个怎么样?

  • 一切都得到了很好的清理吗?看起来我应该在你的`read`之后调用`close`.这有必要吗? (40认同)
  • 当urlopen超出范围时,urlopen返回的对象将被删除(并最终确定,并将其关闭).因为Cpython是引用计数的,所以你可以在`read`之后立即依赖它.但是对于Jython等来说,`with`块会更清晰,更安全. (28认同)
  • 它不适用于仅支持HTTPS的网站.`requests`工作正常 (7认同)
  • 如果您正在使用**Amazon Lambda**并且需要获取URL,那么2.x解决方案可用且内置.它似乎也适用于https.它只不过是`r = urllib2.urlopen("http://blah.com/blah")`然后是`text = r.read()`.它是同步的,只是等待"文本"中的结果. (6认同)
  • 关闭它是一个好习惯,但是如果你正在寻找一个快速的单行,你可以省略它.:-) (4认同)
  • 与“请求”相比有什么优点/缺点? (2认同)
  • 请参阅[我应该在urllib.urlopen()之后调用close()吗?](/sf/ask/106584551/)以获取详细说明. (2认同)

小智 394

您可以使用名为requests的库.

import requests
r = requests.get("http://example.com/foo/bar")
Run Code Online (Sandbox Code Playgroud)

这很容易.然后你可以这样做:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)
Run Code Online (Sandbox Code Playgroud)

  • @lawphotog这可以使用python3,但你必须`pip install requests`. (5认同)
  • @JoeBlow 请记住,您必须导入外部库才能使用它们 (2认同)
  • 甚至 urllib2 标准库也推荐 requests (2认同)

小智 29

如果你想让httplib2的解决方案成为oneliner考虑实例化匿名Http对象

import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")
Run Code Online (Sandbox Code Playgroud)


小智 19

看看httplib2,它旁边有许多非常有用的功能 - 提供你想要的.

import httplib2

resp, content = httplib2.Http().request("http://example.com/foo/bar")
Run Code Online (Sandbox Code Playgroud)

其中content将是响应主体(作为字符串),resp将包含状态和响应标头.

它不包含在标准的python安装中(但它只需要标准的python),但它绝对值得一试.


小智 15

实际上,在 Python 中,我们可以像从文件中一样从 HTTP 响应中读取数据,下面是从 API 读取 JSON 的示例。

import json
from urllib.request import urlopen

with urlopen(url) as f:
    resp = json.load(f)

return resp['some_key']
Run Code Online (Sandbox Code Playgroud)

  • 这是一个旧的请求/答案,但我发现了其中的价值,因为它具有我可以抓住的优雅的“with...”语法。 (5认同)
  • 这个问题增加了价值,因为它使用了 with 结构,该结构在投票最高和接受的答案的评论中进行了很多讨论,但缺乏它。 (2认同)

Cir*_*四事件 7

如何同时发送标头

Python 3:

import urllib.request
contents = urllib.request.urlopen(urllib.request.Request(
    "https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/latest",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)
Run Code Online (Sandbox Code Playgroud)

Python 2:

import urllib2
contents = urllib2.urlopen(urllib2.Request(
    "https://api.github.com",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)
Run Code Online (Sandbox Code Playgroud)


mic*_*l_s 6

无需进一步必要的导入,此解决方案(对我而言)有效 - 也适用于 https:

try:
    import urllib2 as urlreq # Python 2.x
except:
    import urllib.request as urlreq # Python 3.x
req = urlreq.Request("http://example.com/foo/bar")
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36')
urlreq.urlopen(req).read()
Run Code Online (Sandbox Code Playgroud)

在标题信息中未指定“用户代理”时,我经常难以抓取内容。然后通常请求会被取消,例如:urllib2.HTTPError: HTTP Error 403: Forbiddenurllib.error.HTTPError: HTTP Error 403: Forbidden


the*_*ler 5

这是Python中的wget脚本:

# From python cookbook, 2nd edition, page 487
import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print
Run Code Online (Sandbox Code Playgroud)


Xua*_*uan 5

theller的wget解决方案非常有用,但是,我发现它并没有打印整个下载过程中的进度.如果在reporthook中的print语句后添加一行,这是完美的.

import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
    sys.stdout.flush()
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print
Run Code Online (Sandbox Code Playgroud)


Jun*_*zed 5

足够简单了urllib3

像这样导入它:

import urllib3

pool_manager = urllib3.PoolManager()
Run Code Online (Sandbox Code Playgroud)

并发出这样的请求:

example_request = pool_manager.request("GET", "https://example.com")

print(example_request.data.decode("utf-8")) # Response text.
print(example_request.status) # Status code.
print(example_request.headers["Content-Type"]) # Content type.
Run Code Online (Sandbox Code Playgroud)

您也可以添加标题:

example_request = pool_manager.request("GET", "https://example.com", headers = {
    "Header1": "value1",
    "Header2": "value2"
})
Run Code Online (Sandbox Code Playgroud)

  • 非常适合您可以轻松提供 HTTP 动词的事实 (2认同)