2009-05-09 7 views
41

urlopenコールが行われたときにurllib2がページ全体を取得しますか?Python:urllib2.urlopen呼び出しからHTTPヘッダーを取得しますか?

ページを取得せずにHTTP応答ヘッダーを読み取るだけです。 urllib2はHTTP接続を開き、その後実際の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 

答えて

42

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

urllib2.urlopen(URL [データ]は、[タイムアウト])

...

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

  • geturl() - 取得されたリソースのURLを返します。リダイレクトが行われたかどうかを判断するためによく使用されます。
  • 情報() - あなたの例のために、そう

(HTTPヘッダへのクイックリファレンスを参照してください)httplib.HTTPMessageインスタンスの形式では、このようなヘッダーとして、ページのメタ情報を返しますあなたが探しているものについては、response.info().headersの結果をステップアップしてみてください。

httplib.HTTPMessageを使用する際の主な注意点は、python issue 4773に記載されています。

+17

*** Python 3注意***まず、 'response.info().headers'のようなものはありません。' dict(response.info()) 'を実行してください。次に、HTTPステータスコードに対して 'response.status'を実行します。 – treecoder

+1

**これは**ヘッダーのみを取得するか**ヘッダーのみを**印刷するかですか? –

+2

'headers'はどこに文書化されていますか?また、キー値dictを返す 'response.info()。items()'の使用を検討してください。 –

40

通常のGETリクエストではなくHEADリクエストを送信することはどうでしょうか。次のようにsnipped(同様のものからコピーされたquestion)はまさにそうです。

>>> 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')] 
+2

私はそれを行うだろうと思います! – shigeta

8

urllib2.urlopenは(HTTP GET(またはPOSTあなたがデータ引数を指定した場合)、ないHTTPのHEADを行い、それは後者なかった場合、あなたはreadlinesを行うことができませんでしたか、他のページ本体にアクセスし、もちろん)。

+0

ああ、ありがとう - それは質問に答えます – shigeta

20

実際、urllib2はHTTP HEAD要求を行うことができます。

上記の@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のネットワークプロトコルanalazerのようなものでこれを確認した場合、あなたはそれが実際にではなくGETよりも、HEADリクエストを送信していることがわかります。

これはWiresharkのにより捕捉されるように、上記のコードからのHTTPリクエストとレスポンスである:

HEAD/doFeT HTTP/1.1
は受け入れ-エンコーディング:同一
ホスト: bit.ly
接続:閉じます
ユーザエージェント:Python-urllib/2。7

HTTP/1.1 301は
サーバー移動:nginxの
日:日、2012年2月19日午後01時20分56秒GMT
のContent-Type:text/htmlのを。 charset = utf-8
キャッシュ制御:プライベート。 MAX-年齢= 90
場所: http://www.kidsidebyside.org/?p=445
MIME-バージョン:1.0
のContent-Length:127
接続:クローズ
のSet-Cookie: _bit = 4f40f738-00153-02ed0-421cf10a;ドメイン= .bit.ly。 expires = Fri Aug 17 13:20:56 2012; path = /;他の質問のコメントの1で述べたように、当該URLがリダイレクトが含まれている場合HttpOnlyの

はしかし、その後、urllib2のが先ではなく、HEADにGETリクエストを行います。 HEADリクエストだけを本当にしたい場合、これは大きな欠点になる可能性があります。

上記のリクエストにはリダイレクトが含まれます。

GET/2009/05 /来-とドロー・サークル・オブ・ユニティと-US/HTTP/1.1
のAccept-エンコード:ここでのWiresharkで撮影して目的地への要求は、あります:アイデンティティ
ホスト:www.kidsidebyside.org
接続:クローズ
のUser-Agent:Pythonの-urllibは/ 2.7

urllib2のを使用する代わりにジョー・グレゴリオの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
受け入れエンコード:gzipで、 を収縮
ユーザーエージェント:Pythonの-httplib2/0.7.2(gzipの

は、ここで最初のリクエストです)

ここで、第2の要求は、先にいます:

HEAD/2009/05 /来-とドロー-circle・オブ・ユニティと-US/HTTP/1.1
ホスト:www.kidsidebyside.org
受け入れる-encodingを:GZIPを、
ユーザーエージェントを収縮:Pythonの-httplib2/0.7.2(GZIP)

+0

私は答えを最初に読んだときにそれを見逃しましたが、 'response.info()。dict'はまさに私が探していたものです。これは[docs](https://docs.python.org/2.6/library/mimetools.html#mimetools.Message)で説明されていません。 – Coderer

5

ワンライナー:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))" 
-1
def _GetHtmlPage(self, addr): 
    headers = { 'User-Agent' : self.userAgent, 
      ' Cookie' : self.cookies} 

    req = urllib2.Request(addr) 
    response = urllib2.urlopen(req) 

    print "ResponseInfo=" 
    print response.info() 

    resultsHtml = unicode(response.read(), self.encoding) 
    return resultsHtml 
関連する問題