7

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

1

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

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

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

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

  1. Я предпочёл бы не захватывать вывод, используя wget или curl.

5 ответ(ов)

0

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

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

Таким образом, весь код выполняется в одной строке, и вы сразу получаете ответ и содержимое запроса.

0

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

import json
from urllib.request import urlopen

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

return resp['some_key']

В этом примере мы используем urlopen для открытия URL, после чего читаем содержимое ответа с помощью json.load(). Результат сохраняется в переменной resp, и мы можем получить значение по нужному ключу.

0

Этот код работает (для меня) без дополнительных импортов – также с использованием HTTPS:

try:
    import urllib2 as urlreq  # Python 2.x
except ImportError:
    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.

0

Чтобы отправить заголовки вместе с запросом в Python, вы можете использовать модуль urllib.request в Python 3 или urllib2 в Python 2. Пример ниже показывает, как это сделать для API GitHub, чтобы получить последние релизы.

Python 3:

import urllib.request

# Создание запроса с заголовками
request = urllib.request.Request(
    "https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/latest",
    headers={"Accept": 'application/vnd.github.full+json;text/html'}
)

# Открытие URL и чтение содержимого
contents = urllib.request.urlopen(request).read()
print(contents)

Python 2:

import urllib2

# Создание запроса с заголовками
request = urllib2.Request(
    "https://api.github.com",
    headers={"Accept": 'application/vnd.github.full+json;text/html'}
)

# Открытие URL и чтение содержимого
contents = urllib2.urlopen(request).read()
print(contents)

В обоих примерах мы создаем запрос с определёнными заголовками, используя словарь. Заголовок "Accept" указывает серверу, в каком формате мы ожидаем получить ответ.

0

Ваша проблема с отсутствием прогресса при загрузке с помощью wget действительно важна. Решение theller'а полезно, но вы можете улучшить его, добавив одну строку после оператора print в функции reporthook. Вот улучшенный код с отображением прогресса:

import sys, urllib

def reporthook(a, b, c):
    # Выводим прогресс в процентах
    print("% 3.1f%% из %d байт\r" % (min(100, float(a * b) / c * 100), c), end="")
    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()  # Печатаем новую строку по окончании загрузки

Обратите внимание, что я добавил end="" в print, чтобы избежать перехода на новую строку, и теперь при каждом обновлении прогресса информация будет выводиться на одной строке. Также стоит упомянуть, что для использования этой функции вам нужно выполнять скрипт с аргументами, перечисляющими URL-адреса, которые нужно загрузить.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь