使用Python

时间:2015-10-02 12:20:43

标签: python selenium-webdriver web-scraping selenium-chromedriver disqus

首先,我为模糊的标题道歉,但问题是我不确定导致错误的原因。

我正在使用Python来推断网站上的一些数据。 我创建的代码在当时传递一个链接时效果很好,但是当我尝试从我拥有的8000个页面中收集数据时它会以某种方式中断(它实际上已经破坏了)。我需要做的是:

  1. 从一个页面收集所有链接(8000个链接)
  2. 从每个链接推断iframe中包含的另一个链接
  3. 从2中的链接中删除日期。
  4. 第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]中的索引超出范围),但每次都有不同的链接。如果我使用单个链接检查我的代码,代码可以正常工作,那么它实际上可以在那里找到网址。当然,有时会通过它之前停止的链接,它没有任何问题。 我怀疑我得到这个因为可能是超时,但我当然不确定。

    那么,我怎么能理解这个问题呢?

    如果问题是请求太多(即使是睡眠),我该如何处理?

    谢谢。

1 个答案:

答案 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