【问题标题】:Selenium iterating over paginator: optimizationSelenium 迭代分页器:优化
【发布时间】:2016-09-28 08:57:22
【问题描述】:

我有一个带有分页器的网站。每个页面显示 32 个链接,我获取每个链接并将它们存储在文件夹中的单独文件中。我在 Python 中使用 Selenium 的 Firefox 驱动程序。

程序基本上是:

get the 32 elements
for element in elements:
    open new file and save element
repeat

我正在监控每个周期所花费的时间。我从 4 秒开始,然后是 8 秒(当时我保存了 10000 个链接),现在花了 10 秒,我已经保存了 13000 个链接。

以前,我打开同一个文件并附加链接,这也减慢了周期,我猜是因为随着文件大小的增加,它必须在每个周期中加载并附加。

但现在我不知道是什么会减缓周期。转到下一页总是花费 3-4 秒,所以这不是问题的根源。什么可能会减慢周期?

这是循环:

while True:
    propiedades = driver.find_elements_by_xpath("//*[@class='hlisting']")
    info_propiedades = [propiedad.find_element_by_xpath(".//*[@class='propertyInfo item']")
                        for propiedad in propiedades]

    for propiedad in info_propiedades:
        try:
            link = [l.get_attribute("href") for l in propiedad.find_elements_by_xpath(".//a")]
            thelink = link[0]
            id_ = thelink.split("id-")[-1]
            with open(os.path.join(linkspath, id_), "w") as f:
                f.write(link[0])
            numlinks += 1
        except:
            print("link not found")

    siguiente = driver.find_element_by_id("paginador_pagina_{0}".format(paginador))
    siguiente.click()  # goes to the next page
    while new_active_page == old_active_page:  # checks if page has loaded completely
        try:
            new_active_page = driver.find_element_by_class_name("pagina_activa").text
        except:
            new_active_page = old_active_page
        time.sleep(0.3)
    old_active_page = new_active_page
    paginador += 1

【问题讨论】:

标签: python selenium pagination


【解决方案1】:

一些建议...

  1. 一开始你有很多嵌套的.find_elements_*。您应该能够制作一个找到您正在寻找的元素的单一发现。从站点和您的代码来看,您似乎获得了类似于“MC1595226”的代码。如果您获取其中一个 MC 代码并在 HTML 中进行搜索,您会在该特定列表中找到该代码。它在 URL 中,是一堆元素的 id 的一部分,等等。找到此代码的更快方法是使用 CSS 选择器 "a[id^='btnContactResultados_'"。它搜索包含以“btnContactResultados_”开头的 id 的 A 标签。该 id 的其余部分是 MC 编号,例如

    <a id="btnContactResultados_MC1595226" ...>
    

    因此,使用该 CSS 选择器,我们可以找到所需的元素,然后获取 ID 并用“_”分割它并获取最后一部分。注意:这更多的是代码效率。我认为这不会使您的脚本运行得非常快,但它应该会加快搜索部分的速度。

  2. 我建议每页写一个日志,每页只写一次。所以基本上你处理页面的代码并将结果附加到列表中。处理完页面的所有代码后,您将该列表写入日志。写入磁盘很慢......你应该尽可能少地这样做。最后,您可以编写一个小脚本来打开所有这些文件并将它们附加到一个文件中以获得最终产品。您还可以做一些中间立场,即每页写入一次文件,但在关闭该文件并使用不同的文件之前写入 100 页到文件。您必须尝试使用​​这些设置才能获得最佳性能。

如果我们将这两者的逻辑结合起来,我们会得到这样的结果......

while True:
    links = driver.find_elements_by_css_selector("a[id^='btnContactResultados_'")

    codes = []
    for link in links:
        codes.append(link.get_attribute("id").split("_")[-1])

    with open(os.path.join(linkspath, paginador), "w") as f:
        f.write(codes)
    driver.find_element_by_link_text("Siguiente »").click()  # this should work

    while new_active_page == old_active_page:  # checks if page has loaded completely
        try:
            new_active_page = driver.find_element_by_class_name("pagina_activa").text
        except:
            new_active_page = old_active_page
        time.sleep(0.3)
    old_active_page = new_active_page
    paginador += 1

注意:python 不是我的母语...我更喜欢 Java/C#,因此您可能会在此处发现错误、效率低下或非 Python 代码。您已被警告... :)

【讨论】:

  • 让我试试吧! :P
  • 这也摆脱了 Element is no longer attach to DOM 错误。谢谢!
  • 我正在从 Selenium 中清除 Firefox 的缓存,它也有了很大的改进!我还保存了每 5000 个链接的链接。我目前读了13000,每个周期花费3-4秒。
  • 我想说的是,我从未使用过它,但我听说 BeautifulSoup 擅长快速抓取页面。如果你想走得更快,你可以考虑一下。
  • 我稍后会用它来做这件事。第一步是获取链接,然后我打开它们并提取信息。与 BeautifulSoup
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 2010-10-22
  • 2021-07-25
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
相关资源
最近更新 更多