HTTP GET วิธีที่เร็วที่สุดใน Python คืออะไร?


613

เป็นวิธีที่เร็วที่สุดใน HTTP GET ใน Python ถ้าฉันรู้ว่าเนื้อหาจะเป็นสตริง? ฉันกำลังค้นหาเอกสารสำหรับหนึ่งซับด่วนอย่างรวดเร็วเช่น:

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

แต่ทั้งหมดที่ฉันสามารถค้นหาโดยใช้ Google มีhttplibและurllib- และผมไม่สามารถที่จะหาทางลัดในห้องสมุดเหล่านั้น

Python 2.5 มาตรฐานมีทางลัดในบางรูปแบบข้างต้นหรือฉันควรจะเขียนฟังก์ชั่นurl_getหรือไม่?

  1. ฉันไม่ต้องการที่จะจับการส่งออกของปลอกกระสุนออกไปหรือwgetcurl

ฉันพบสิ่งที่ฉันต้องการที่นี่: stackoverflow.com/a/385411/1695680
ThorSummoner

คำตอบ:


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

เอกสารและurllib.requestread


44
ทุกอย่างได้รับการทำความสะอาดอย่างดีหรือไม่? มันดูเหมือนว่าฉันควรจะเรียกหลังจากที่คุณclose readจำเป็นไหม?
แฟรงก์ครูเกอร์

4
เป็นวิธีปฏิบัติที่ดีในการปิด แต่ถ้าคุณกำลังมองหาสายการบินเดียวที่รวดเร็วคุณสามารถละเว้นได้ :-)
Nick Presta

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 installlib ลงบนอินสแตนซ์ของ AWS Linux (แลมบ์ดาตัวแปรที่เหมือนกันใน OS) แล้วคัดลอกไฟล์เหล่านั้นแทนดังนั้นคุณจะมีความเข้ากันได้ไบนารีกับ AWS Linux ไลบรารีเดียวที่คุณไม่สามารถใช้ในแลมบ์ดาได้คือไลบรารีที่มีการแจกแจงแบบไบนารี่เท่านั้นซึ่งค่อนข้างหายาก
Chris Johnson

6
@lawphotog งานนี้จะมี python3 pip install requestsแต่คุณต้อง
akarilimano

แม้แต่
ไลบรารี่

เกี่ยวกับแลมบ์ดา: หากคุณต้องการใช้คำขอในฟังก์ชั่น AWS แลมบ์ดา มีไลบรารีคำขอ 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")

โดยที่เนื้อหาจะเป็นเนื้อหาการตอบสนอง (เป็นสตริง) และ resp จะมีสถานะและส่วนหัวการตอบกลับ

มันไม่ได้มาพร้อมกับการติดตั้งหลามแบบมาตรฐาน (แต่มันต้องใช้งูหลามมาตรฐานเท่านั้น) แต่มันคุ้มค่าที่จะเช็คเอาท์


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ปลอดภัยกว่าและง่ายกว่าการใช้งานมากกว่า builtin urllib.requestหรือhttpโมดูลและมีความเสถียร


1
ดีมากสำหรับความจริงที่ว่าคุณสามารถให้คำกริยา HTTP ได้อย่างง่ายดาย
Tom

5

วิธีแก้ปัญหาสำหรับ wget นั้นมีประโยชน์จริง ๆ แต่ฉันพบว่ามันไม่ได้พิมพ์ความคืบหน้าตลอดกระบวนการดาวน์โหลด มันสมบูรณ์แบบถ้าคุณเพิ่มหนึ่งบรรทัดหลังคำสั่งพิมพ์ใน 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()

ฉันมักจะมีปัญหาในการคว้าเนื้อหาเมื่อไม่ระบุ "User-Agent" ในข้อมูลส่วนหัว แล้วมักจะร้องขอจะถูกยกเลิกกับสิ่งที่ชอบหรือurllib2.HTTPError: HTTP Error 403: Forbiddenurllib.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 APIs โดยเฉพาะนอกจากนี้ยังมีทางเลือกที่สะดวกสบายมากขึ้นเช่น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

จริงๆแล้วในไพ ธ อนเราสามารถอ่านได้จาก 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.