Какой самый быстрый способ получить HTTP GET в Python?

613

Какой самый быстрый способ получить HTTP GET в Python, если я знаю, что содержимое будет строкой? Я ищу документацию для быстрого однострочного:

contents = url.get("http://example.com/foo/bar")

Но все, что я могу найти с помощью Google, - httplibи urllib- и я не могу найти ярлык в этих библиотеках.

Есть ли в стандартном Python 2.5 ярлык в той или иной форме, как указано выше, или мне следует написать функцию url_get?

  1. Я бы предпочел не фиксировать результат обстрела на wgetили curl.
Фрэнк Крюгер
источник
Я нашел то, что мне было нужно здесь: stackoverflow.com/a/385411/1695680
ThorSummoner

Ответы:

872

Python 3:

import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()

Python 2:

import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()

Документация для urllib.requestа read.

Ник преста
источник
44
Все хорошо очищается? Похоже, я должен позвонить closeпосле вашего read. Это необходимо?
Фрэнк Крюгер
4
Это хорошая практика, чтобы закрыть его, но если вы ищете быстрый однострочный, вы можете опустить его. :-)
Ник Преста
28
Объект, возвращенный urlopen, будет удален (и завершен, что закрывает его), когда он выйдет из области видимости. Поскольку Cpython подсчитывает ссылки, вы можете положиться на это сразу после read. Но withблок будет более понятным и безопасным для Jython и т. Д.
sah
8
Он не работает с HTTPS-сайтами. requestsотлично работает
OverCoder
6
Если вы используете Amazon Lambda и вам нужен URL, решение 2.x доступно и встроено. Кажется, он работает и с https. Это не более чем r = urllib2.urlopen("http://blah.com/blah")и тогда text = r.read(). Это синхрон, просто ждет результата в «тексте».
Толстяк
412

Вы можете использовать библиотеку под названием запросы .

import requests
r = requests.get("http://example.com/foo/bar")

Это довольно просто. Тогда вы можете сделать так:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)
Алекс К
источник
1
@JoeBlow помните, что вы должны импортировать внешние библиотеки, чтобы использовать их
MikeVelazco
1
Почти любая библиотека Python может быть использована в AWS Lambda. Для чистого Python вам просто нужно «продать» эту библиотеку (копировать в папки вашего модуля, а не использовать pip install). Для не чистых библиотек есть дополнительный шаг - вам нужно загрузить pip installlib на экземпляр AWS Linux (тот же вариант ОС, под которым запускаются лямбды), а затем скопировать эти файлы, чтобы иметь двоичную совместимость с AWS Linux. Единственные библиотеки, которые вы не всегда сможете использовать в Lambda, - это библиотеки с бинарным дистрибутивом, которые, к счастью, довольно редки.
Крис Джонсон
6
@lawphotog это работает с python3, но вы должны pip install requests.
akarilimano
Даже стандартная библиотека urllib2 рекомендует запросы
Asfand Qazi
Что касается Lambda: если вы хотите использовать запросы в функциях AWS Lambda. Также есть предустановленная библиотека запросов boto3. from botocore.vendored import requests Использование response = requests.get('...')
kmjb
29

Если вы хотите, чтобы решение с httplib2 было oneliner, рассмотрите возможность создания анонимного объекта Http

import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")
к Chomik
источник
19

Взгляните на httplib2 , который - наряду с множеством очень полезных функций - предоставляет именно то, что вы хотите.

import httplib2

resp, content = httplib2.Http().request("http://example.com/foo/bar")

Где содержимое будет телом ответа (в виде строки), и соответственно будет содержать статус и заголовки ответа.

Он не входит в стандартную установку Python (но требует только стандартный Python), но это определенно стоит проверить.

hennr
источник
6

Это достаточно просто с мощной 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 .

urllib3гораздо безопаснее и проще в использовании, чем встроенные модули urllib.requestили httpмодули, и является стабильным.

Juniorized
источник
1
отлично
Том
5

Решение theller для wget действительно полезно, однако я обнаружил, что оно не распечатывает процесс загрузки. Идеально, если вы добавите одну строку после оператора print в 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
Сюань
источник
4

Вот скрипт wget на Python:

# 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
theller
источник
4

Без дальнейшего необходимого импорта это решение работает (для меня) - также с 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()

У меня часто возникают трудности с захватом контента, если в информации заголовка не указан «Агент пользователя». Затем обычно запросы отменяются чем-то вроде: urllib2.HTTPError: HTTP Error 403: Forbiddenили urllib.error.HTTPError: HTTP Error 403: Forbidden.

michael_s
источник
4

Как также отправлять заголовки

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)

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)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
2

Если вы работаете именно с HTTP API, есть и более удобные варианты, такие как Nap .

Например, вот как можно получить информацию о Github с 1 мая 2014 года :

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

Киммо
источник
2

Отличные решения Сюань, Теллер.

Для работы с 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.

Akshar
источник
1

Для python >= 3.6, вы можете использовать dload :

import dload
t = dload.text(url)

Для json:

j = dload.json(url)

Установка:
pip install dload

CONvid19
источник
0

На самом деле в Python мы можем читать из URL, как из файлов, вот пример для чтения JSON из API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']
Катрыч Тарас
источник
Хотя мы благодарим вас за ваш ответ, было бы лучше, если бы он предоставил дополнительную ценность поверх других ответов. В этом случае ваш ответ не дает дополнительной ценности, поскольку другой пользователь уже опубликовал это решение. Если предыдущий ответ был вам полезен, вы должны проголосовать за него, а не повторять ту же информацию.
Тоби Спейт
0

Если вы хотите 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)
Juniorized
источник