PythonでHTTP GETを行う最も速い方法は何ですか?


613

コンテンツが文字列になることがわかっている場合、PythonでHTTP GETを実行する最も簡単な方法は何ですか?私はドキュメントのような簡単なワンライナーを探しています:

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

回答:


872

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.requestおよびのドキュメントread


44
すべてがうまくクリーンアップされていますか?私はcloseあなたの後に電話する必要があるようreadです。それは必要ですか?
フランククルーガー

4
クローズすることをお勧めしますが、簡単なワンライナーを探している場合は、省略できます。:-)
Nick Presta

28
urlopenによって返されたオブジェクトは、スコープから外れると削除(およびファイナライズされて閉じます)されます。Cpythonは参照カウントされるため、の直後に発生することを信頼できますread。しかし、withブロックはJythonなどにとってより明確で安全です
sah

8
HTTPSのみのWebサイトでは機能しません。requests
正常に

6
Amazon Lambdaを使用していて、URLを取得する必要がある場合は、2.xソリューションが利用可能であり、組み込まれています。httpsでも動作するようです。それはそれ以上のものではr = urllib2.urlopen("http://blah.com/blah")ありませんtext = r.read()。それは同期で、「テキスト」で結果を待つだけです。
Fattie 2016

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のインスタンス(同じOSバリアントラムダで実行されます)にlibを実行し、代わりにそれらのファイルをコピーして、AWS Linuxとのバイナリ互換性を確保する必要があります。Lambdaで常に使用できるわけではない唯一のライブラリは、バイナリ配布のみのライブラリで、ありがたいことに非常にまれです。
クリスジョンソン

6
@lawphotogこれはpython3で動作しますが、する必要がありますpip install requests
akarilimano 2018

urllib2標準ライブラリでさえリクエストを推奨しています
Asfand Qazi

Lambdaに関して:AWS Lambda関数でリクエストを使用したい場合。プリインストールされたboto3リクエストライブラリもあります。 from botocore.vendored import requests 使用状況 response = requests.get('...')
kmjb

29

httplib2でのソリューションをワンライナーにしたい場合は、匿名の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にはステータスヘッダーと応答ヘッダーが含まれます。

ただし、標準の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動詞を簡単に提供できるという点で素晴らしい
Tom

5

Thellerのwgetソリューションは本当に便利ですが、ダウンロードプロセス全体の進捗状況が出力されないことがわかりました。reporthookのprintステートメントの後に1行追加すると完璧です。

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

Pythonのwgetスクリプトは次のとおりです。

# 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: Forbiddenまたはurllib.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 APIを使用している場合は、Napなどのより便利な選択肢もあります。

たとえば、2014年5月1日以降、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())

その他の例: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.6dloadを使用できます。

import dload
t = dload.text(url)

の場合json

j = dload.json(url)

インストール:
pip install dload


0

実際、Pythonでは、ファイルなどのURLから読み取ることができます。以下は、APIからjsonを読み取る例です。

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.