Який найшвидший спосіб отримати 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

Відповіді:


870

Пітон 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.


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(). Це синхронізація, вона просто чекає результату в "тексті".
Fattie

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 installвкласти в екземпляр AWS Linux (той самий варіант ОС лямбда, який працює під ним), а потім скопіювати ці файли замість цього, щоб мати двійкову сумісність з AWS Linux. Єдині бібліотеки, які ви не завжди зможете використовувати в Lambda, - це лише бінарні дистрибутиви, які, на щастя, є досить рідкісними.
Кріс Джонсон

6
@lawphotog це працює з python3, але ви повинні pip install requests.
акарілімано

Навіть стандартна бібліотека 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

Погляньте на httpsb2 , який - поряд із безліччю дуже корисних функцій - забезпечує саме те, що ви хочете.

import httplib2

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

Якщо вміст буде тілом відповіді (як рядок), а resp міститиме заголовки стану та відповідей.

Він не входить в комплект із стандартною установкою 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
чудово, що ви можете легко надати дієслово HTTP
Том,

5

Рішення Theller для wget є дуже корисним, однак я виявив, що він не роздруковує прогрес у процесі завантаження. Ідеально, якщо ви додасте один рядок після заяви про друк у звіті.

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

Як також надсилати заголовки

Пітон 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)

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

Відмінні рішення Xuan, 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-адреси.


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']

Хоча ми дякуємо вам за вашу відповідь, було б краще, якби вона надала додаткову цінність поверх інших відповідей. У цьому випадку ваша відповідь не надає додаткового значення, оскільки інший користувач вже розмістив це рішення. Якщо попередня відповідь була вам корисною, вам слід проголосувати за неї, а не повторювати ту саму інформацію.
Toby Speight

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.