如果我知道内容将是一个字符串,那么在 Python 中进行 HTTP GET 的最快方法是什么?我正在搜索文档以获取快速的单行代码,例如:
contents = url.get("http://example.com/foo/bar")
但我使用 Google 能找到的只有 httplib
和 urllib
- 我无法在这些库中找到快捷方式。
标准 Python 2.5 是否具有上述某种形式的快捷方式,或者我应该编写一个函数 url_get
?
我不希望将炮击的输出捕获到 wget 或 curl。
蟒蛇 3:
import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()
蟒蛇2:
import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()
urllib.request
和 read
的文档。
使用 Requests 库:
import requests
r = requests.get("http://example.com/foo/bar")
然后你可以做这样的事情:
>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content) # bytes
>>> print(r.text) # r.content as str
通过运行以下命令安装请求:
pip install requests
pip install
)。对于非纯库,有一个额外的步骤 - 您需要将库 pip install
放到 AWS Linux 的实例上(运行相同的操作系统变体 lambda),然后复制这些文件,以便您与 AWS 具有二进制兼容性Linux。唯一不能在 Lambda 中使用的库是那些只有二进制发行版的库,谢天谢地,这种库非常少见。
pip install requests
。
from botocore.vendored import requests
用法response = requests.get('...')
如果您希望使用 httplib2 的解决方案成为 oneliner,请考虑实例化匿名 Http 对象
import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")
看看 httplib2,除了许多非常有用的功能之外,它提供了您想要的东西。
import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")
其中 content 将是响应正文(作为字符串),而 resp 将包含状态和响应标头。
虽然它不包含在标准 python 安装中(但它只需要标准 python),但它绝对值得一试。
使用强大的 urllib3
库就足够简单了。
像这样导入它:
import urllib3
http = urllib3.PoolManager()
并提出这样的请求:
response = http.request('GET', 'https://example.com')
print(response.data) # Raw data.
print(response.data.decode('utf-8')) # Text.
print(response.status) # Status code.
print(response.headers['Content-Type']) # Content type.
您也可以添加标题:
response = http.request('GET', 'https://example.com', headers={
'key1': 'value1',
'key2': 'value2'
})
更多信息可以在 urllib3 documentation 上找到。
urllib3
比内置 urllib.request
或 http
模块更安全、更易于使用,并且稳定。
实际上,在 Python 中,我们可以从文件中读取 HTTP 响应,这是从 API 读取 JSON 的示例。
import json
from urllib.request import urlopen
with urlopen(url) as f:
resp = json.load(f)
return resp['some_key']
with...
语法。
无需进一步必要的导入,此解决方案就可以工作(对我而言)- 也可以使用 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()
在标题信息中未指定“User-Agent”时,我经常难以抓取内容。然后通常使用以下内容取消请求:urllib2.HTTPError: HTTP Error 403: Forbidden
或 urllib.error.HTTPError: HTTP Error 403: Forbidden
。
Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136
。不知道如何找出最新的 Microsoft Edge UA string
,但这里的答案正确地暗示了解决它的方法。
如何发送标头
蟒蛇 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)
蟒蛇2:
import urllib2
contents = urllib2.urlopen(urllib2.Request(
"https://api.github.com",
headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)
theller 的 wget 解决方案非常有用,但是,我发现它不会在整个下载过程中打印出进度。如果您在reporthook 中的打印语句之后添加一行,那就完美了。
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
这是 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
如果您想要较低级别的 API:
import http.client
conn = http.client.HTTPSConnection('example.com')
conn.request('GET', '/')
resp = conn.getresponse()
content = resp.read()
conn.close()
text = content.decode('utf-8')
print(text)
优解轩,Theller。
为了让它与 python 3 一起工作,请进行以下更改
import sys, urllib.request
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.request.urlretrieve(url, file, reporthook)
print
此外,您输入的 URL 应该以“http://”开头,否则会返回未知 url 类型错误。
如果您专门使用 HTTP API,还有更方便的选择,例如 Nap。
例如,以下是自 2014 年 5 月 1 日以来从 Github 获取要点的方法:
from nap.url import Url
api = Url('https://api.github.com')
gists = api.join('gists')
response = gists.get(params={'since': '2014-05-01T00:00:00Z'})
print(response.json())
更多示例:https://github.com/kimmobrunfeldt/nap#examples
对于 python >= 3.6
,您可以使用 dload:
import dload
t = dload.text(url)
对于 json
:
j = dload.json(url)
安装:
pip install dload
dload
库,即使没有多少用户使用它,一些这不是答案的要求。只是一个猜测,但我认为您没有正确理解这个问题,但阅读其他答案可能会给您提供线索,因为还推荐了许多不同的库。
read
之后调用close
。那有必要吗?read
之后立即发生的情况。但是对于 Jython 等来说,with
块会更清晰、更安全。requests
工作正常r = urllib2.urlopen("http://blah.com/blah")
然后是text = r.read()
。它是同步的,它只是等待“文本”中的结果。