web-dev-qa-db-ja.com

Pythonリダイレクトに従ってページをダウンロードしますか?

私は次のpythonスクリプトを持っていますが、それは美しく機能します。

import urllib2

url = 'http://abc.com' # write the url here

usock = urllib2.urlopen(url)
data = usock.read()
usock.close()

print data

ただし、指定したURLの一部は2回以上リダイレクトされる場合があります。どうすればpythonリダイレクトが完了するのを待ってからデータをロードできますか。たとえば、上記のコードを

http://www.google.com/search?hl=en&q=KEYWORD&btnI=1

これは、Google検索でimラッキーボタンを押すことと同じです。

>>> url = 'http://www.google.com/search?hl=en&q=KEYWORD&btnI=1'
>>> usick = urllib2.urlopen(url)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 400, in open
    response = meth(req, response)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 513, in http_response
    'http', request, response, code, msg, hdrs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 438, in error
    return self._call_chain(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 372, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 521, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden
>>> 

私は(URL、データ、タイムアウト)を試しましたが、何をそこに置くべきかわかりません。

編集:私は実際にリダイレクトしないで、最初のリンクのヘッダーを使用したかどうかを実際に見つけました。次のリダイレクトの場所を取得し、それを最終的なリンクとして使用できます

23
Cripto

リダイレクト処理を制御するためのより優れたAPIを備えたRequestsライブラリを使用した方がよい場合があります。

http://docs.python-requests.org/en/latest/user/quickstart/#redirection-and-history

リクエスト:

http://pypi.python.org/pypi/requests/ (人間のurllibの置換)

19
Mikko Ohtamaa

他の回答状態としてrequestsを使用します。これが例です。リダイレクトはr.urlになります。以下の例では、httphttpsにリダイレクトされます

HEADの場合:

In [1]:     import requests
   ...:     r = requests.head('http://github.com', allow_redirects=True)
   ...:     r.url

Out[1]: 'https://github.com/'

忘れる:

In [1]:     import requests
   ...:     r = requests.get('http://github.com')
   ...:     r.url

Out[1]: 'https://github.com/'

HEADの場合はallow_redirectsを指定する必要がありますが、そうでない場合はヘッダーで取得できますが、これはお勧めしません。

In [1]: import requests

In [2]: r = requests.head('http://github.com')

In [3]: r.headers.get('location')
Out[3]: 'https://github.com/'

ページをダウンロード GETが必要な場合、r.contentを使用してページにアクセスできます。

2
Glen Thompson