作为使用 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)
如果您足够熟悉,您可以设置自己的 User-Agent 字符串而不使用fake_useragent
. 在这种情况下,只需ua.chrome
用您的用户代理字符串替换该部分。但是,正如您所看到的,requests
在这种情况下甚至不需要标题就可以工作 - 如果您想提高技能,这是一个可行的选择,可以在将来为您省去一些麻烦。
编辑:只是添加我的个人经验。我发现调试这些问题的一种好方法是保存您的代码检索到的页面,并将其与您在实际浏览器中看到的页面进行比较。通过这种方式,您将知道某些内容是否是 JS 驱动的(因此无法通过简单的抓取来解析),或者您是否收到完全不同的内容(这意味着您的抓取缺少页面期望的某些元素,例如标题或 JS 支持) )。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句