Python遵循重定向然后下载页面?

Cri*_*pto 25 html python web-scraping

我有以下python脚本,它工作得很漂亮.

import urllib2

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

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

print data
Run Code Online (Sandbox Code Playgroud)

但是,我给它的一些URL可能会重定向它2次或更多次.在加载数据之前,如何让python等待重定向完成.例如,使用上面的代码时

http://www.google.com/search?hl=en&q=KEYWORD&btnI=1
Run Code Online (Sandbox Code Playgroud)

这是在谷歌搜索上点击我的幸运按钮的等价物,我得到:

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

我试过(网址,数据,超时)然而,我不确定要放在那里.

编辑:我实际上发现,如果我不重定向,只是使用第一个链接的标题,我可以抓住下一个重定向的位置,并使用它作为我的最后一个链接

Mik*_*maa 20

使用Requests库可能会更好,它具有更好的API来控制重定向处理:

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

要求:

http://pypi.python.org/pypi/requests/(urllib替代人类)

  • @ user1048138:你介意告诉我们你找到了什么来解决你的问题吗? (5认同)

Gle*_*son 20

使用requests作为对方的回答状态,这里有一个例子。重定向将在r.url. 在下面的示例中,http重定向到https

对于头部:

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

Out[1]: 'https://github.com/'
Run Code Online (Sandbox Code Playgroud)

忘记:

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

Out[1]: 'https://github.com/'
Run Code Online (Sandbox Code Playgroud)

注意 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/'
Run Code Online (Sandbox Code Playgroud)

下载您需要 GET的页面,然后您可以使用r.content