51

呼び出しが行われ urllib2たときにページ全体をフェッチしますか?urlopen

ページを取得せずにHTTP応答ヘッダーを読みたいだけです。urllib2HTTP接続を開き、その後実際のHTMLページを取得するように見えます...それとも、urlopen呼び出しでページのバッファリングを開始するだけですか?

import urllib2
myurl = 'http://www.kidsidebyside.org/2009/05/come-and-draw-the-circle-of-unity-with-us/'
page = urllib2.urlopen(myurl) // open connection, get headers

html = page.readlines()  // stream page
4

6 に答える 6

52

メソッドを使用しresponse.info()てヘッダーを取得します。

urllib2 ドキュメントから:

urllib2.urlopen(url[, データ][, タイムアウト])

...

この関数は、次の 2 つのメソッドを追加したファイルのようなオブジェクトを返します。

  • geturl() — 取得したリソースの URL を返します。一般に、リダイレクトが行われたかどうかを判断するために使用されます
  • info() — ページのメタ情報 (ヘッダーなど) を httplib.HTTPMessage インスタンスの形式で返します (HTTP ヘッダーのクイック リファレンスを参照)。

したがって、あなたの例では、response.info().headers探しているものの結果をステップ実行してみてください。

httplib.HTTPMessage の使用に関する主な警告は、python issue 4773に記載されていることに注意してください。

于 2009-10-29T00:17:31.327 に答える
41

通常のGETリクエストの代わりにHEADリクエストを送信するのはどうですか。次の切り抜き(同様の質問からコピー)はまさにそれを行います。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]
于 2009-05-09T14:17:34.550 に答える
22

実際、urllib2はHTTPHEADリクエストを実行できるようです。

上記の@retoがリンクしている質問は、urllib2にHEADリクエストを実行させる方法を示しています。

これが私の見解です:

import urllib2

# Derive from Request class and override get_method to allow a HEAD request.
class HeadRequest(urllib2.Request):
    def get_method(self):
        return "HEAD"

myurl = 'http://bit.ly/doFeT'
request = HeadRequest(myurl)

try:
    response = urllib2.urlopen(request)
    response_headers = response.info()

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response_headers.dict

except urllib2.HTTPError, e:
    # Prints the HTTP Status code of the response but only if there was a 
    # problem.
    print ("Error code: %s" % e.code)

Wiresharkネットワークプロトコルアナライザーのようなものでこれをチェックすると、GETではなく実際にHEADリクエストを送信していることがわかります。

これは、Wiresharkによってキャプチャされた、上記のコードからのHTTP要求と応答です。

HEAD / doFeT HTTP / 1.1
Accept-Encoding:identity
Host:bit.ly
Connection:close
User-Agent:Python-urllib / 2.7

HTTP / 1.1 301移動
サーバー:nginx
日付:2012年2月19日日曜日13:20:56 GMT
コンテンツタイプ:text / html; charset = utf-8
キャッシュ制御:プライベート; max-age = 90
場所: http
://www.kidsidebyside.org/?p = 445 MIME-Version:1.0
Content-Length:127
接続:close
Set-Cookie:_bit = 4f40f738-00153-02ed0-421cf10a; domain = .bit.ly; Expires = Fri Aug 17 13:20:56 2012; path = /; HttpOnly

ただし、他の質問のコメントの1つで述べたように、問題のURLにリダイレクトが含まれている場合、urllib2はHEADではなく宛先に対してGET要求を実行します。本当にHEADリクエストのみを行いたい場合、これは大きな欠点になる可能性があります。

上記のリクエストにはリダイレクトが含まれます。Wiresharkによってキャプチャされた宛先へのリクエストは次のとおりです。

GET / 2009/05 / come-and-draw-the-circle-of-unity-with-us / HTTP / 1.1
Accept-Encoding:identity
Host:www.kidsidebyside.org
Connection:close
User-Agent:Python-urllib / 2.7

urllib2を使用する代わりに、JoeGregorioのhttplib2ライブラリを使用することもできます。

import httplib2

url = "http://bit.ly/doFeT"
http_interface = httplib2.Http()

try:
    response, content = http_interface.request(url, method="HEAD")
    print ("Response status: %d - %s" % (response.status, response.reason))

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response.__dict__

except httplib2.ServerNotFoundError, e:
    print (e.message)

これには、最初のHTTPリクエストと宛先URLへのリダイレクトされたリクエストの両方にHEADリクエストを使用するという利点があります。

これが最初のリクエストです:

HEAD / doFeT HTTP / 1.1
ホスト:bit.ly
accept-encoding:gzip、deflate
user-agent:Python-httplib2 / 0.7.2(gzip)

宛先への2番目のリクエストは次のとおりです。

HEAD / 2009/05 / come-and-draw-the-circle-of-unity-with-us / HTTP / 1.1
ホスト:www.kidsidebyside.org
accept-encoding:gzip、deflate
user-agent:Python-httplib2 / 0.7 .2(gzip)

于 2012-02-19T14:27:46.290 に答える
8

urllib2.urlopenは、HTTPHEADではなくHTTPGET(またはデータ引数を指定した場合はPOST)を実行します(後者を実行した場合、もちろん、ページ本体へのreadlineやその他のアクセスは実行できません)。

于 2009-05-09T14:18:33.533 に答える
5

一発ギャグ:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))"
于 2012-03-30T08:11:23.743 に答える