python urllib.request - 可能有效的标头

Posted

技术标签:

【中文标题】python urllib.request - 可能有效的标头【英文标题】:python urllib.request - headers that are likely to work 【发布时间】:2016-10-14 16:12:49 【问题描述】:

编写一个从网站获取信息的小脚本。我遇到了 HTTP 错误问题。

req = urllib.request.Request(lnk['href'],
   headers='User-Agent': 'Mozilla/5.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
page = urllib.request.urlopen(req)

例如,当尝试获取 http://www.guru99.com/node-js-tutorial.html 时,我会收到一长串错误,以 406 Unacceptable 结尾:

Traceback (most recent call last):
  File "get_links.py", line 45, in <module>
    page = urllib.request.urlopen(req)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 162, in urlopen
    return opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 471, in open
    response = meth(req, response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 581, in http_response
    'http', request, response, code, msg, hdrs)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 509, in error
    return self._call_chain(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 443, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 589, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 406: Not Acceptable

谷歌搜索我发现我应该修复标题(就像我在上面所做的那样)以及很多关于如何修复标题的教程。除了 - 实际上没有多少工作。

是否有一些不错的标头可能不会对大多数网站造成问题?是否有其他人创建的一些 python 模块已经包含常用的标头?有没有一种好方法可以用不同的标头重试几次,直到得到良好的响应?

这似乎是每个使用 Python 进行网络抓取的人都会遇到的问题,而我还没有找到合适的解决方案。

【问题讨论】:

【参考方案1】:

HTTP 错误 406 不可接受

超文本传输​​协议 (HTTP) 406 Not Acceptable 客户端错误 响应码表示服务器无法产生响应 匹配请求中定义的可接受值列表 主动内容协商标头,并且服务器是 不愿提供默认表示。

所以我可以看到问题在于您的 User-Agent: Mozilla/5.0 键和值。这是一堆正确的用户代理的链接,

devicesatlsas.com developer.chrome.com developer.mozilla.org

所以把你的代码改成下面这样,

headers='User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')

我知道答案为时已晚,但希望这对其他人有所帮助。

【讨论】:

在不久的将来有一些抓取工作要做,今天出现在我的收件箱中。感谢您花时间在四滴眼泪之后。 (哇,这四年也太奇怪了!)【参考方案2】:

以下标题集似乎适用于大多数测试。如果其他人有建议,请提供。如果一组不起作用,我也对尝试不同标头的良好解决方案感兴趣。

req = urllib.request.Request(lnk['href'],
   headers='User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36')
page = urllib.request.urlopen(req)

【讨论】:

【参考方案3】:

我尝试了您的代码,但得到了与预期相同的错误。

我也尝试使用我的 Chrome 浏览器提供的用户代理,这似乎有效

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36

.. 并且在不通过显式标头的情况下运行测试,该标头也返回 http 200(成功)。这将使用库提供的默认标头,例如

python-requests/2.10.0

希望对你有帮助

【讨论】:

以上是关于python urllib.request - 可能有效的标头的主要内容,如果未能解决你的问题,请参考以下文章

爬虫小探-Python3 urllib.request获取页面数据

Python 3.5 urllib.request 403 禁止错误

urllib.request.Request

Python爬虫--Urllib库

[Python系列-19]:爬虫 - urllib.request.urlopen()和urllib.request.get()的使用区别

Python3 urllib.request库的基本使用