Python 3.6.2 url.request.urlopen() urllib.error.HTTPError: H



我试图使用Python 3.6.2从Google Finances的网站上抓取一些数据。这是代码:

import urllib.request
url="https://www.google.com/search?num=40&newwindow=1&tbm=fin&q="
stockName=input("The stock you want to search for:")
url=url+stockName
url="https://www.google.com/search?num=40&newwindow=1&tbm=fin&q=FB"
data=urllib.request.urlopen(url).read()`

但是我一直收到HTTP错误403。 我得到的错误是这样的:

Traceback (most recent call last):
File "<pyshell#101>", line 1, in <module>
data=urllib.request.urlopen(url).read()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 223, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 532, in open
response = meth(req, response)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 642, in http_response
'http', request, response, code, msg, hdrs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 564, in error
result = self._call_chain(*args)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 756, in http_error_302
return self.parent.open(new, timeout=req.timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 532, in open
response = meth(req, response)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 642, in http_response
'http', request, response, code, msg, hdrs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 570, in error
return self._call_chain(*args)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 650, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

我该怎么办?在此之前,我收到SSL证书错误,但由于在此论坛中找到答案而解决了。

某些站点不一定支持无头抓取,无论是由于缺少正确的标头还是缺少防止机器人的 JS 支持。 它将返回 403 状态或超出预期的其他状态。 我对urllib不够熟悉,无法发表评论,但是当我使用requests模块尝试时,它似乎有效。

import requests
res = requests.get("https://www.google.com/search?num=40&newwindow=1&tbm=fin&q=FB")
res.raise_for_status()
# No status raised

您可能还想尝试urllib2. 我提到的两个库都需要从pip安装。

存在针对urllib的解决方案。 您需要手动添加标头。 就个人而言,我使用fake_useragent库(再次从 pip 安装)来欺骗标头:

from fake_useragent import UserAgent
from urllib import request
ua = UserAgent()
req = request.Request("https://www.google.com/search?num=40&newwindow=1&tbm=fin&q=FB")
req.add_header('User-Agent', ua.chrome)
data = request.urlopen(req)

如果您足够熟悉,则可以设置自己的用户代理字符串,而无需使用fake_useragent。 在这种情况下,只需将ua.chrome部分替换为您的用户代理字符串即可。 正如你所看到的,在这种情况下,requests甚至不需要标题就可以工作 - 如果你准备提高你的技能组合,这是一个可行的选择,可能会在未来为你省去一些麻烦。

编辑:只是为了添加我的个人经验。 我发现调试这些问题的一个好方法是保存代码检索到的页面,并将其与您在实际浏览器中看到的内容进行比较。 通过这种方式,您将知道某些内容是否是JS驱动的(因此无法通过简单的抓取进行解析),或者您是否收到完全不同的内容(这意味着您的废料缺少页面期望的某些元素,例如标头或JS支持)。

最新更新