Was ist der schnellste Weg zu HTTP GET in Python?


613

Was ist der schnellste Weg zu HTTP GET in Python, wenn ich weiß, dass der Inhalt eine Zeichenfolge ist? Ich suche in der Dokumentation nach einem schnellen Einzeiler wie:

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

Aber alles, was ich mit Google finden kann, sind httplibund urllib- und ich kann in diesen Bibliotheken keine Verknüpfung finden.

Hat Standard Python 2.5 eine Verknüpfung in irgendeiner Form wie oben, oder sollte ich eine Funktion schreiben url_get?

  1. Ich würde es vorziehen, die Ausgabe des Beschusses an wgetoder nicht zu erfassen curl.

Ich habe hier gefunden, was ich brauchte: stackoverflow.com/a/385411/1695680
ThorSummoner

Antworten:


870

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()

Dokumentation für urllib.requestund read.


44
Wird alles schön aufgeräumt? Es sieht so aus, als sollte ich closenach deinem anrufen read. Ist das notwendig
Frank Krueger

4
Es ist empfehlenswert, es zu schließen, aber wenn Sie nach einem schnellen Einzeiler suchen, können Sie es weglassen. :-)
Nick Presta

28
Das von urlopen zurückgegebene Objekt wird gelöscht (und finalisiert, wodurch es geschlossen wird), wenn es außerhalb des Gültigkeitsbereichs liegt. Da Cpython als Referenz gezählt wird, können Sie sich darauf verlassen, dass dies unmittelbar nach dem read. Aber ein withBlock wäre klarer und sicherer für Jython usw.
sah

8
Es funktioniert nicht mit Nur-HTTPS-Websites. requestsfunktioniert gut
OverCoder

6
Wenn Sie Amazon Lambda verwenden und eine URL benötigen, ist die 2.x-Lösung verfügbar und integriert. Es scheint auch mit https zu funktionieren. Es ist nichts weiter als r = urllib2.urlopen("http://blah.com/blah")und dann text = r.read(). Es ist synchron, es wartet nur auf das Ergebnis in "Text".
Fattie

412

Sie können eine Bibliothek namens Anfragen verwenden .

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

Das ist ganz einfach. Dann können Sie so vorgehen:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)

1
@ JoeBlow denken Sie daran, dass Sie die externen Bibliotheken importieren müssen, um sie zu verwenden
MikeVelazco

1
Fast jede Python-Bibliothek kann in AWS Lambda verwendet werden. Für reines Python müssen Sie nur diese Bibliothek "herstellen" (in die Ordner Ihres Moduls kopieren, anstatt sie zu verwenden pip install). Für nicht reine Bibliotheken gibt es einen zusätzlichen Schritt: Sie müssen pip installdie Bibliothek auf eine Instanz von AWS Linux (dieselbe Lambdas-Variante der Betriebssystemvariante, auf der sie ausgeführt werden) und anschließend diese Dateien kopieren, damit Sie binär mit AWS Linux kompatibel sind. Die einzigen Bibliotheken, die Sie in Lambda nicht immer verwenden können, sind solche mit nur binären Verteilungen, die zum Glück ziemlich selten sind.
Chris Johnson

6
@lawphotog das funktioniert mit python3, aber du musst pip install requests.
Akarilimano

Sogar die urllib2 Standardbibliothek empfiehlt Anfragen
Asfand Qazi

In Bezug auf Lambda: Wenn Sie Anforderungen in AWS Lambda-Funktionen verwenden möchten. Es gibt auch eine vorinstallierte boto3-Anforderungsbibliothek. from botocore.vendored import requests Verwendung response = requests.get('...')
kmjb

29

Wenn Sie möchten, dass die Lösung mit httplib2 ein Oneliner ist, sollten Sie ein anonymes HTTP-Objekt instanziieren

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

19

Schauen Sie sich httplib2 an , das neben vielen sehr nützlichen Funktionen genau das bietet, was Sie wollen.

import httplib2

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

Wobei Inhalt der Antworttext (als Zeichenfolge) wäre und resp den Status und die Antwortheader enthalten würde.

Es ist zwar nicht in einer Standard-Python-Installation enthalten (erfordert jedoch nur Standard-Python), aber es lohnt sich auf jeden Fall, es sich anzusehen.


6

Mit der leistungsstarken urllib3Bibliothek ist das ganz einfach .

Importiere es so:

import urllib3

http = urllib3.PoolManager()

Und stellen Sie eine Anfrage wie folgt:

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.

Sie können auch Header hinzufügen:

response = http.request('GET', 'https://example.com', headers={
    'key1': 'value1',
    'key2': 'value2'
})

Weitere Informationen finden Sie in der urllib3-Dokumentation .

urllib3ist viel sicherer und einfacher zu bedienen als das eingebaute urllib.requestoder die httpModule und ist stabil.


1
ideal für die Tatsache, dass Sie leicht ein HTTP-Verb bereitstellen können
Tom

5

Die Lösung von theller für wget ist wirklich nützlich, aber ich habe festgestellt, dass sie den Fortschritt während des gesamten Downloadvorgangs nicht druckt. Es ist perfekt, wenn Sie eine Zeile nach der Druckanweisung in reporthook einfügen.

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

Hier ist ein Wget-Skript in 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

Ohne weitere notwendige Importe funktioniert diese Lösung (für mich) - auch mit 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()

Ich habe oft Schwierigkeiten, den Inhalt abzurufen, wenn ich keinen "User-Agent" in den Header-Informationen angegeben habe. Dann werden die Anfragen normalerweise mit etwas wie: urllib2.HTTPError: HTTP Error 403: Forbiddenoder storniert urllib.error.HTTPError: HTTP Error 403: Forbidden.


4

So senden Sie auch Header

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

Wenn Sie speziell mit HTTP-APIs arbeiten, gibt es auch bequemere Optionen wie Nap .

So erhalten Sie beispielsweise seit dem 1. Mai 2014 Informationen von 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())

Weitere Beispiele: https://github.com/kimmobrunfeldt/nap#examples


2

Hervorragende Lösungen Xuan, Theller.

Nehmen Sie die folgenden Änderungen vor, damit es mit Python 3 funktioniert

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

Vor der von Ihnen eingegebenen URL sollte außerdem ein "http: //" stehen, da sonst ein unbekannter URL-Typfehler zurückgegeben wird.


1

Für python >= 3.6können Sie dload verwenden :

import dload
t = dload.text(url)

Für json:

j = dload.json(url)

Installieren:
pip install dload


0

Tatsächlich können wir in Python aus URLs wie aus Dateien lesen. Hier ist ein Beispiel für das Lesen von json aus der API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']

Obwohl wir uns für Ihre Antwort bedanken, wäre es besser, wenn sie zusätzlich zu den anderen Antworten einen zusätzlichen Wert liefern würde. In diesem Fall bietet Ihre Antwort keinen zusätzlichen Wert, da ein anderer Benutzer diese Lösung bereits veröffentlicht hat. Wenn eine vorherige Antwort für Sie hilfreich war, sollten Sie sie abstimmen, anstatt dieselben Informationen zu wiederholen.
Toby Speight

0

Wenn Sie eine API auf niedrigerer Ebene wünschen:

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.