python – 在VPS上运行Selenium webdriver时出现各种Urllib2错误
|
我正在使用带有 Python绑定的Selenium来从具有无头Firefox的网页中抓取AJAX内容.它在我的本地机器上运行时效果很好.当我在我的VPS上运行完全相同的脚本时,会在看似随机(但一致)的行上抛出错误.我的本地和远程系统具有相同的操作系统/体系结构,因此我猜测与VPS相关的区别. 对于每个回溯,该行在引发错误之前运行4次. 在执行JavaScript以将元素滚动到视图中时,我经常会遇到此URLError. File "google_scrape.py",line 18,in _get_data
driver.execute_script("arguments[0].scrollIntoView(true);",e)
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",line 396,in execute_script
{'script': script,'args':converted_args})['value']
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",line 162,in execute
response = self.command_executor.execute(driver_command,params)
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/remote_connection.py",line 355,in execute
return self._request(url,method=command_info[0],data=data)
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/remote_connection.py",line 402,in _request
response = opener.open(request)
File "/usr/lib64/python2.7/urllib2.py",line 404,in open
response = self._open(req,data)
File "/usr/lib64/python2.7/urllib2.py",line 422,in _open
'_open',req)
File "/usr/lib64/python2.7/urllib2.py",line 382,in _call_chain
result = func(*args)
File "/usr/lib64/python2.7/urllib2.py",line 1214,in http_open
return self.do_open(httplib.HTTPConnection,line 1184,in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [Errno 111] Connection refused>
偶尔我会从元素中读取文本时得到BadStatusLine. File "google_scrape.py",line 19,in _get_data
if e.text.strip():
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",line 55,in text
return self._execute(Command.GET_ELEMENT_TEXT)['value']
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py",line 233,in _execute
return self._parent.execute(command,params)
File "/home/ryne/.virtualenvs/DEV/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py",line 1187,in do_open
r = h.getresponse(buffering=True)
File "/usr/lib64/python2.7/httplib.py",line 1045,in getresponse
response.begin()
File "/usr/lib64/python2.7/httplib.py",line 409,in begin
version,status,reason = self._read_status()
File "/usr/lib64/python2.7/httplib.py",line 373,in _read_status
raise BadStatusLine(line)
httplib.BadStatusLine: ''
有几次我收到了套接字错误: File "google_scrape.py",line 365,in _read_status
line = self.fp.readline(_MAXLINE + 1)
File "/usr/lib64/python2.7/socket.py",line 476,in readline
data = self._sock.recv(self._rbufsize)
socket.error: [Errno 104] Connection reset by peer
我是在没有代理的情况下从Google上抓取的,所以我首先想到的是我的IP地址被识别为VPS并被置于5次页面操作限制之下.但我最初的研究表明,这些错误不会因为被阻止而产生. 任何洞察这些错误意味着什么,或从VPS发出HTTP请求时必要的考虑因素将非常感激. 更新 经过一番思考并研究一下webdriver究竟是什么 – 自动浏览器输入 – 我应该对为什么remote_connection.py完全发出urllib2请求感到困惑.看起来WebElement类的text方法是python绑定的“额外”功能,它不是Selenium核心的一部分.这并不能解释上述错误,但可能表明文本方法不应用于抓取. 更新2 我意识到,就我的目的而言,Selenium唯一的功能是加载ajax内容.所以在页面加载后,我用lxml解析源代码而不是用Selenium获取元素,即: html = lxml.html.fromstring(driver.page_source) 但是,page_source是另一种导致调用urllib2的方法,并且我第二次使用它时一直得到BadStatusLine错误.最小化urllib2请求绝对是朝着正确方向迈出的一步. 更新3 通过使用javascript抓取源来消除urllib2请求更好: html = lxml.html.fromstring(driver.execute_script("return window.document.documentElement.outerHTML"))
结论 通过在每个请求之间执行time.sleep(10)可以避免这些错误.我提出的最佳解释是,谷歌的防火墙将我的IP识别为VPS,因此将其置于更严格的阻止规则之下. 这是我最初的想法,但我仍然觉得很难相信,因为我的网络搜索没有返回任何迹象表明上述错误可能是由防火墙引起的. 如果是这种情况,我认为可以通过代理规避更严格的规则,尽管该代理可能必须是本地系统或托管以避免相同的限制. 解决方法根据我们的对话,您发现即使是少量的每日搜索,Google也会采用防刮方法.解决方案是在每次获取之间延迟几秒钟.在一般情况下,由于您在技术上将不可恢复的成本转移给第三方,因此尝试减少放置在远程服务器上的额外资源负载始终是一种好习惯.如果没有HTTP提取之间的暂停,快速服务器和连接可能会导致远程拒绝服务,尤其是刮掉没有Google服务器资源的目标. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
