首先,我为模糊的标题道歉,但问题是我不确定导致错误的原因。
我正在使用Python来推断网站上的一些数据。 我创建的代码在当时传递一个链接时效果很好,但是当我尝试从我拥有的8000个页面中收集数据时它会以某种方式中断(它实际上已经破坏了)。我需要做的是:
第1点很简单,工作正常。 第2点和第3点工作了一段时间,然后我得到一些错误。每次在不同的点,它永远不会相同。经过一些测试后,我决定尝试不同的方法并运行我的代码,直到第1点的所有链接上的第2点,尝试首先收集所有链接。在这一点上,我发现,可能,我在这个阶段得到了错误。 代码的工作原理如下:在for循环中,我将url列表中的每个项目传递给下面的函数。它应该搜索到Disqus网站的链接。应该只有一个链接,总有一个链接。因为库是lxml,所以无法在iframe内扫描,我使用selenium和ChromeDriver。
def get_url(webpage_url):
chrome_driver_path= '/Applications/chromedriver'
driver = webdriver.Chrome(chrome_driver_path)
driver.get(webpage_url)
iframes=driver.find_elements_by_tag_name("iframe")
list_urls=[]
urls=[]
# collects all the urls of all the iframe tags
for iframe in iframes:
driver.switch_to_frame(iframe)
time.sleep(3)
list_urls.append(driver.current_url)
driver.switch_to_default_content()
driver.quit()
for item in list_urls:
if item.startswith('http://disqus'):
urls.append(item)
if len(urls)>1:
print "too many urls collected in iframes"
else:
url=urls[0]
return url
一开始没有time.sleep,它适用于大约30个链接。然后我放了一个time.sleep(2)它到达了大约60.现在有time.sleep(3)它适用于大约130个链接。当然,这不是一个解决方案。我现在得到的错误,它始终是相同的(url = urls [0]中的索引超出范围),但每次都有不同的链接。如果我使用单个链接检查我的代码,代码可以正常工作,那么它实际上可以在那里找到网址。当然,有时会通过它之前停止的链接,它没有任何问题。 我怀疑我得到这个因为可能是超时,但我当然不确定。
那么,我怎么能理解这个问题呢?
如果问题是请求太多(即使是睡眠),我该如何处理?
谢谢。
答案 0 :(得分:3)
根据您对问题的描述,当您在给定时间内发出太多请求时,主机可能会限制您的客户端。这是一种常见的保护措施,可以替代DoS攻击和不良行为机器人 - 就像你的一样。
这里的干净解决方案是检查网站是否有robots.txt文件,如果这样解析它并尊重规则 - 否则,在两个请求之间设置足够长的等待时间,这样就不会被踢。
此外,您还可以解决其他一些问题 - 404,丢失网络连接等问题 - 甚至加载selenium.webdriver
as documented here时出现问题:
取决于几个因素,包括OS /浏览器组合, WebDriver可能会也可能不会等待页面加载。在一些 在某些情况下,WebDriver可能会在页面出现之前返回控件 装完,甚至开始装货。为了确保稳健性,您需要 使用Explicit和等待页面中存在的元素 隐含等待。
wrt /你的IndexError,你盲目地假设你至少得到一个网址(这意味着至少有一个iframe),这可能不是上述任何原因(以及其他一些原因) 。首先,您要确保正确处理所有极端情况,然后修复代码,这样您就不会认为做至少有一个网址:
url = None
if len(urls) > 1:
print "too many urls collected in iframes"
elif len(urls) == 0:
url = urls[0]
else:
print "no url found"
此外,如果您想要的只是您可以找到的第一个http://disqus网址,则无需全部收集,然后将其过滤掉,然后返回第一个:
def get_url(webpage_url):
chrome_driver_path= '/Applications/chromedriver'
driver = webdriver.Chrome(chrome_driver_path)
driver.get(webpage_url)
iframes=driver.find_elements_by_tag_name("iframe")
# collects all the urls of all the iframe tags
for iframe in iframes:
driver.switch_to_frame(iframe)
time.sleep(3)
if driver.current_url.startswith('http;//disqus'):
return driver.current_url
driver.switch_to_default_content()
driver.quit()
return None # nothing found