【问题标题】:Scraper getting only a few names out of numerousScraper 从众多名字中只得到几个名字
【发布时间】:2017-09-24 18:26:48
【问题描述】:

我在 python 中结合 selenium 编写了一个爬虫,以从 redmart.com 获取所有产品名称。每次我运行我的代码时,我只从那个页面得到 27 个名字,尽管这个页面有很多名字。仅供参考,该页面已启用延迟加载方法。我的刮刀可以到达页面底部,但只能刮掉 27 个名字。我无法理解我在刮板中应用的逻辑迷失了哪里。希望得到任何解决方法。

这是我目前编写的脚本:

from selenium import webdriver; import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)

driver.get("https://redmart.com/new")
check_height = driver.execute_script("return document.body.scrollHeight;")

while True:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    try:
        wait.until(lambda driver: driver.execute_script("return document.body.scrollHeight;")  > check_height)
        check_height = driver.execute_script("return document.body.scrollHeight;") 
    except:
         break

for names in driver.find_elements_by_css_selector('.description'):
    item_name = names.find_element_by_css_selector('h4 a').text
    print(item_name)

driver.quit()

【问题讨论】:

  • 这个网站很好奇。假设您有权抓取该网站(根据他们的使用条款),您可能会向他们寻求帮助。当我向上和向下滚动页面时,只需观察页面的 HTML 变化,它们似乎正在从页面动态加载和卸载内容。这可以解释为什么您的代码只能看到您期望的一小部分项目。也许他们可以为您提供更方便的 API 来访问您需要的信息。
  • @ Breaks Software,我对他们的数据一点也不感兴趣。我想学习的是如何处理我在抓取这样的网站时所面临的情况。
  • 由于它们似乎是动态加载和卸载内容,我不确定是否有一种有效的方法可以使用 Selenium 或任何其他浏览器抓取工具来解决这个问题。您是否尝试在“while”块中包含“for”代码块,将捕获的项目存储在列表/字典/随你所用的任何内容中?

标签: python python-3.x selenium selenium-webdriver web-scraping


【解决方案1】:

您必须等待加载新内容。

这是一个非常简单的例子:

    driver.get('https://redmart.com/new')
    products = driver.find_elements_by_xpath('//div[@class="description"]/h4/a')
    print(len(products))  # 18 products
    driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
    time.sleep(5)  # wait for new content to be loaded
    products = driver.find_elements_by_xpath('//div[@class="description"]/h4/a')
    print(len(products))  # 36 products

有效。

您还可以查看 XHR 请求并尝试在不使用“time.sleep()”和“driver.execute_script”的情况下抓取任何您想要的内容。

例如,在滚动他们的网站时,会从以下 URL 加载新产品: https://api.redmart.com/v1.6.0/catalog/search?q=new&pageSize=18&page=1

如您所见,可以修改 pageSize(最多 100 个产品)和 page 等参数。使用此 URL,您甚至可以在不使用 Selenium 和 Chrome 的情况下抓取所有产品。您可以通过Python Requests 完成所有这些操作

【讨论】:

  • 感谢 mostaszewski,您的回答。你已经在你的例子中展示了我应该让我的爬虫等待一段时间来获取新加载的内容,为此你设置了一个硬编码的延迟,在这种情况下为 5 秒。我对显式等待做了同样的事情,我在上面例子中展示的相同位置做了同样的事情,以放置延迟参数。我哪里错了?
  • 请冷静一下,我以为你在代码中改变了一些东西。问题是您等待脚本执行。这没有意义。您必须等待网站加载完毕。
  • 这行wait.until(lambda driver: driver.execute_script("return document.body.scrollHeight;") > check_height) 在脚本中做了什么?不是要等内容加载完吗?
  • 不,它没有。它只是等待高度值的变化。
  • 这就是我迷路的地方。我认为新加载的内容也与高度值一起出现。非常感谢让我明白。但是,您知道如何通过显式等待获取页面内容吗?
猜你喜欢
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 2016-04-08
相关资源
最近更新 更多