Какой самый быстрый способ получить 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")

19

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

import httplib2

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

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

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


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модули, и является стабильным.


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

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.


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)

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.


1

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

import dload
t = dload.text(url)

Для json:

j = dload.json(url)

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


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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.