【问题标题】:Possible bottle-neck issue in web-scraping with Python使用 Python 进行网络抓取时可能出现的瓶颈问题
【发布时间】:2015-12-30 15:46:18
【问题描述】:

首先我为这个模糊的标题道歉,但问题是我不确定是什么导致了错误。

我正在使用 Python 从网站推断一些数据。 我创建的代码在当时传递一个链接时运行良好,但在尝试从我拥有的 8000 个页面中收集数据时却以某种方式中断(它实际上之前就中断了)。我需要做的过程是这样的:

  1. 从一个页面收集所有链接(8000 个链接)
  2. 从每个链接推断 iframe 中包含的另一个链接
  3. 从2中的链接中抓取日期。

第 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]中的索引超出范围),但每次都有不同的链接。如果我使用中断的单个链接检查我的代码,则代码可以正常工作,因此它实际上可以在那里找到网址。当然,有时会传递一个之前停止的链接,并且它可以正常工作。 我怀疑我得到这个可能是因为超时,但我当然不确定。

那么,我该如何理解这里的问题?

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

谢谢。

【问题讨论】:

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


    【解决方案1】:

    根据您对问题的描述,当您在给定时间内发出过多请求时,主机可能会限制您的客户端。这是针对 DoS 攻击和行为不端的机器人(例如您的机器人)的常见保护措施。

    这里的干净解决方案是检查站点是否有 robots.txt 文件,如果有,则解析它并遵守规则 - 否则,在两个请求之间设置足够长的等待时间,这样你就不会被踢。

    您还可能遇到很多其他问题 - 404、网络连接丢失等 - 甚至是 selenium.webdriver as documented here 的加载时间问题:

    取决于几个因素,包括操作系统/浏览器组合, WebDriver 可能会也可能不会等待页面加载。在一些 在这种情况下,WebDriver 可能会在页面有控制权之前返回 完成,甚至开始加载。为确保稳健性,您需要 使用 Explicit 等待页面中存在的元素和 隐式等待。

    wrt/ 您的 IndexError,您盲目地假设您将获得至少一个 url(这意味着至少一个 iframe),由于上述任何原因(以及其他一些原因),情况可能并非如此。首先,您要确保正确处理所有极端情况,然后修复您的代码,以免您确实拥有至少一个 url:

    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 url,不需要全部收集,然后过滤掉,然后返回第一个:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-07
      • 2022-12-18
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      相关资源
      最近更新 更多