Python'da HTTP GET'e erişmenin en hızlı yolu nedir?


613

İçeriğin bir dize olacağını biliyorsanız, Python'da HTTP GET'in en hızlı yolu nedir? Belgeleri aşağıdaki gibi hızlı bir astar için arıyorum:

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

Ancak Google'ı kullanarak bulabildiğim tek şey bu httplibve urllibbu kütüphanelerde bir kısayol bulamıyorum.

Standart Python 2.5'in yukarıdaki gibi bir şekilde bir kısayolu var mı, yoksa bir işlev url_getmi yazmalıyım ?

  1. Ben wgetveya bombardımanı çıktı yakalamak için tercih etmem curl.

Burada ihtiyacım olanı buldum: stackoverflow.com/a/385411/1695680
ThorSummoner

Yanıtlar:


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

İçin dokümantasyon urllib.requestve read.


44
Her şey güzelce temizleniyor mu? Ben closesenin peşinden çağırmalıyım gibi görünüyor read. Bu gerekli mi?
Frank Krueger

4
Kapatmak iyi bir uygulamadır, ancak hızlı bir tek astar arıyorsanız, bunu atlayabilirsiniz. :-)
Nick Presta

28
Urlopen tarafından döndürülen nesne, kapsam dışına çıktığında silinir (ve kapatılır). Cpython referans sayıldığından, hemen sonrasında olanlara güvenebilirsiniz read. Ancak withJython, vb. İçin bir blok daha net ve daha güvenli olurdu
sah

8
Yalnızca HTTPS web sitelerinde çalışmaz. requestsiyi çalışıyor
OverCoder

6
Amazon Lambda kullanıyorsanız ve bir URL almanız gerekiyorsa, 2.x çözümü kullanılabilir ve yerleşiktir. Https ile de çalışıyor gibi görünüyor. O r = urllib2.urlopen("http://blah.com/blah")zamandan daha fazla bir şey değil text = r.read(). Senkronize, sadece "metin" sonucu bekler.
Fattie

412

İstek adı verilen bir kitaplık kullanabilirsiniz .

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

Bu oldukça kolay. Sonra bunu yapabilirsiniz:

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

1
@JoeBlow bunları kullanmak için harici kütüphaneleri içe aktarmanız gerektiğini unutmayın
MikeVelazco

1
Hemen hemen her Python kütüphanesi AWS Lambda'da kullanılabilir. Saf Python için, sadece o kütüphaneyi "satmanız" gerekir (kullanmak yerine modülünüzün klasörlerine kopyalayın pip install). Saf olmayan kütüphaneler için ekstra bir adım vardır - pip installbir AWS Linux örneğine (altında aynı OS varyant lambdaları çalıştırılır) kopyalamanız ve ardından bu dosyaları kopyalamanız gerekir, böylece AWS Linux ile ikili uyumluluğa sahip olursunuz. Lambda'da her zaman kullanamayacağınız tek kütüphaneler, sadece ikili dağılımları olan kütüphanelerdir, ki bunlar oldukça nadirdir.
Chris Johnson

6
@lawphotog bu python3 ile çalışır, ama yapmak zorunda pip install requests.
akarilimano

Urllib2 standart kütüphanesi bile istekleri öneriyor
Asfand Qazi

Lambda ile ilgili olarak: istekleri AWS Lambda fonksiyonlarında kullanmak istiyorsanız. Önceden yüklenmiş bir boto3 istek kütüphanesi de vardır. from botocore.vendored import requests Kullanım response = requests.get('...')
kmjb

29

Httplib2 ile çözümün oneliner olmasını istiyorsanız, anonim Http nesnesini başlatmayı düşünün

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

19

Pek çok kullanışlı özelliğin yanında tam olarak ne istediğinizi sağlayan httplib2'ye bir göz atın .

import httplib2

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

İçeriğin yanıt gövdesi (dize olarak) ve resp durum ve yanıt başlıklarını içereceği yerlerde.

Olsa da standart bir python yükleme ile birlikte gelmez (ama sadece standart python gerektirir), ama kesinlikle kontrol etmeye değer.


6

Güçlü urllib3kütüphane ile yeterince basit .

Bu şekilde içe aktarın:

import urllib3

http = urllib3.PoolManager()

Ve böyle bir istekte bulunun:

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.

Üstbilgiler de ekleyebilirsiniz:

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

Urllib3 belgelerinde daha fazla bilgi bulunabilir .

urllib3yerleşik urllib.requestveya httpmodüllerden çok daha güvenli ve kullanımı kolaydır ve kararlıdır.


1
kolayca bir HTTP fiili sağlayabilirsiniz
Tom

5

weller için theller'ın çözümü gerçekten yararlıdır, ancak, indirme işlemi boyunca ilerleme yazdırmıyor bulundu. Reporthook'ta print ifadesinden sonra bir satır eklemek mükemmeldir.

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

İşte Python'da bir wget betiği:

# 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

Daha fazla ithalat yapılmadan bu çözüm (benim için) çalışır - ayrıca https ile:

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

Üstbilgi bilgilerinde bir "User-Agent" belirtmediğimde genellikle içeriği kapmakta zorluk çekiyorum. Sonra genellikle istekleri iptal eder: urllib2.HTTPError: HTTP Error 403: Forbiddenveya urllib.error.HTTPError: HTTP Error 403: Forbidden.


4

Üstbilgiler nasıl gönderilir

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

Özellikle HTTP API'leriyle çalışıyorsanız, Nap gibi daha uygun seçenekler de vardır .

Örneğin, 1 Mayıs 2014'ten bu yana Github'dan nasıl özgeçmiş elde edeceğiniz aşağıda açıklanmıştır :

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

Daha fazla örnek: https://github.com/kimmobrunfeldt/nap#examples


2

Mükemmel çözümler Xuan, Theller.

Python 3 ile çalışması için aşağıdaki değişiklikleri yapın

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

Ayrıca, girdiğiniz URL'nin önünde "http: //" olmalıdır, aksi takdirde bilinmeyen bir URL türü hatası döndürür.


1

İçin python >= 3.6, dload'u kullanabilirsiniz :

import dload
t = dload.text(url)

Şunun için json:

j = dload.json(url)

Yüklemek:
pip install dload


0

Aslında python dosyalarda gibi url okuyabilir, İşte API json okumak için bir örnek.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']

Cevabınız için teşekkür etmemize rağmen, diğer cevapların üzerine ek değer sağlaması daha iyi olur. Bu durumda, başka bir kullanıcı bu çözümü zaten gönderdiğinden cevabınız ek değer sağlamaz. Önceki bir yanıt size yardımcı olduysa, aynı bilgileri tekrarlamak yerine oy vermeniz gerekir.
Toby Speight

0

Daha düşük düzeyli bir API istiyorsanız:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.