Cách nhanh nhất để HTTP GET trong Python là gì?


613

Cách nhanh nhất để HTTP GET trong Python nếu tôi biết nội dung sẽ là một chuỗi? Tôi đang tìm kiếm tài liệu cho một lớp lót nhanh như:

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

Nhưng tất cả những gì tôi có thể tìm thấy bằng Google là httpliburllib- và tôi không thể tìm thấy lối tắt trong các thư viện đó.

Python tiêu chuẩn 2.5 có một phím tắt ở một số dạng như trên không, hay tôi nên viết một hàm url_get?

  1. Tôi không muốn nắm bắt đầu ra của pháo kích ra wgethoặc curl.

Tôi đã tìm thấy những gì tôi cần ở đây: stackoverflow.com/a/385411/1695680
ThorSummoner

Câu trả lời:


872

Con trăn 3:

import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()

Con trăn 2:

import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()

Tài liệu cho urllib.requestread.


44
Có phải mọi thứ được làm sạch độc đáo? Có vẻ như tôi nên gọi closesau của bạn read. Điều đó có cần thiết không?
Frank Krueger

4
Đó là một thực hành tốt để đóng nó, nhưng nếu bạn đang tìm kiếm một lớp lót nhanh, bạn có thể bỏ qua nó. :-)
Nick Presta

28
Đối tượng được trả về bởi urlopen sẽ bị xóa (và hoàn thành, đóng nó) khi nó nằm ngoài phạm vi. Vì Cpython được tính tham chiếu, bạn có thể dựa vào điều đó xảy ra ngay sau read. Nhưng một withkhối sẽ rõ ràng và an toàn hơn cho Jython, v.v.
sah 27/12/13

8
Nó không hoạt động với các trang web chỉ HTTPS. requestshoạt động tốt
OverCoder

6
Nếu bạn đang sử dụng Amazon Lambda và cần lấy URL, giải pháp 2.x có sẵn và tích hợp sẵn. Nó dường như cũng hoạt động với https. Không có gì hơn r = urllib2.urlopen("http://blah.com/blah")và sau đó text = r.read(). Đó là đồng bộ hóa, nó chỉ chờ kết quả trong "văn bản".
Fattie

412

Bạn có thể sử dụng một thư viện gọi là yêu cầu .

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

Điều này khá dễ dàng. Sau đó, bạn có thể làm như thế này:

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

1
@JoeBlow hãy nhớ rằng bạn phải nhập các thư viện bên ngoài để sử dụng chúng
MikeVelazco

1
Hầu như bất kỳ thư viện Python nào cũng có thể được sử dụng trong AWS Lambda. Đối với Python thuần túy, bạn chỉ cần "cung cấp" thư viện đó (sao chép vào các thư mục của mô-đun thay vì sử dụng pip install). Đối với các thư viện không thuần túy, có thêm một bước - bạn cần chuyển pip installsang phiên bản AWS Linux (cùng một phiên bản lambdas chạy trên hệ điều hành), sau đó sao chép các tệp đó để bạn có khả năng tương thích nhị phân với AWS Linux. Các thư viện duy nhất bạn sẽ không thể luôn sử dụng trong Lambda là những thư viện chỉ có phân phối nhị phân, rất hiếm khi xảy ra.
Chris Johnson

6
@lawph photo điều này DOES hoạt động với python3, nhưng bạn phải làm pip install requests.
akarilimano

Ngay cả thư viện tiêu chuẩn urllib2 cũng đề xuất các yêu cầu
Asfand Qazi

Liên quan đến Lambda: nếu bạn muốn sử dụng các yêu cầu trong các chức năng AWS Lambda. Có một thư viện yêu cầu boto3 được cài đặt sẵn cũng có. from botocore.vendored import requests Cách sử dụng response = requests.get('...')
kmjb

29

Nếu bạn muốn giải pháp với omeplib2 trở thành oneliner, hãy xem xét việc khởi tạo đối tượng http ẩn danh

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

19

Hãy xem omeplib2 , bên cạnh rất nhiều tính năng rất hữu ích - cung cấp chính xác những gì bạn muốn.

import httplib2

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

Trong đó nội dung sẽ là nội dung phản hồi (dưới dạng chuỗi) và resp sẽ chứa trạng thái và tiêu đề phản hồi.

Nó không đi kèm với cài đặt python tiêu chuẩn mặc dù (nhưng nó chỉ yêu cầu python tiêu chuẩn), nhưng nó chắc chắn đáng để kiểm tra.


6

Nó đủ đơn giản với urllib3thư viện mạnh mẽ .

Nhập nó như thế này:

import urllib3

http = urllib3.PoolManager()

Và đưa ra yêu cầu như thế này:

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.

Bạn cũng có thể thêm tiêu đề:

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

Thông tin thêm có thể được tìm thấy trên tài liệu urllib3 .

urllib3an toàn và dễ sử dụng hơn nhiều so với nội dung urllib.requesthoặc httpmô-đun và ổn định.


1
tuyệt vời cho thực tế, bạn có thể dễ dàng cung cấp một HTTP động từ
Tom

5

Giải pháp của weller cho wget thực sự hữu ích, tuy nhiên, tôi thấy nó không in ra tiến trình trong suốt quá trình tải xuống. Thật hoàn hảo nếu bạn thêm một dòng sau câu lệnh in trong bản in lại.

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

Đây là một kịch bản wget trong 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

Nếu không cần nhập thêm, giải pháp này hoạt động (đối với tôi) - cũng với 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()

Tôi thường gặp khó khăn khi lấy nội dung khi không chỉ định "Tác nhân người dùng" trong thông tin tiêu đề. Sau đó, thường các yêu cầu bị hủy với một cái gì đó như: urllib2.HTTPError: HTTP Error 403: Forbiddenhoặc urllib.error.HTTPError: HTTP Error 403: Forbidden.


4

Làm thế nào để gửi tiêu đề

Con trăn 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)

Con trăn 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

Nếu bạn đang làm việc với các API HTTP cụ thể, cũng có nhiều lựa chọn thuận tiện hơn như Nap .

Ví dụ: đây là cách lấy ý chính từ Github kể từ ngày 1 tháng 5 năm 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())

Ví dụ khác: https://github.com/kimmobrunfeldt/nap#examples


2

Giải pháp tuyệt vời Xuân, Theller.

Để nó hoạt động với python 3, hãy thực hiện các thay đổi sau

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

Ngoài ra, URL bạn nhập phải được đặt trước "http: //", nếu không, nó sẽ trả về lỗi loại url không xác định.


1

Đối với python >= 3.6, bạn có thể sử dụng dload :

import dload
t = dload.text(url)

Dành cho json:

j = dload.json(url)

Tải về:
pip install dload


0

Trên thực tế trong python chúng ta có thể đọc từ các url như từ các tệp, đây là một ví dụ để đọc json từ API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']

Mặc dù chúng tôi cảm ơn bạn vì câu trả lời của bạn, nhưng sẽ tốt hơn nếu nó cung cấp giá trị bổ sung trên đầu các câu trả lời khác. Trong trường hợp này, câu trả lời của bạn không cung cấp giá trị bổ sung, vì một người dùng khác đã đăng giải pháp đó. Nếu một câu trả lời trước đó hữu ích cho bạn, bạn nên bỏ phiếu thay vì lặp lại thông tin tương tự.
Toby Speight

0

Nếu bạn muốn API cấp thấp hơn:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.