【问题标题】:Python Selenium won't select all image tagsPython Selenium 不会选择所有图像标签
【发布时间】:2020-12-24 16:29:07
【问题描述】:

我正在尝试使用 Selenium 抓取 Product Hunt

更具体地说,我正在尝试获取所有产品图标的源链接。

HTML:

我的爬取代码如下:

driver = webdriver.Chrome("<Your driver's path>")
driver.get("https://www.producthunt.com/topics/seo-tools?order=most-upvoted")
time.sleep(4)
icons = driver.find_elements_by_css_selector("div.styles_thumbnail__d2DAK.styles_thumbnail__XBHZ_ img")
print(len(icons))
print(icons)
driver.close()

问题是 selenium 只获得前 3 张图片,而不是所有可用的产品。

我已尝试增加睡眠时间,并与EC.presence_of_all_elements_located 一起实现了 driver.wait 方式,以确保正确加载所有图标。

【问题讨论】:

    标签: python selenium xpath css-selectors webdriverwait


    【解决方案1】:

    由于在页面底部滚动时会显示其他图标,因此您可以这样做

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get("https://www.producthunt.com/topics/seo-tools?order=most-upvoted")
    
    expected_number_of_icons = 20
    
    icons = []
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        icons = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, "//div[contains(@data-test, 'post-item')]//div[@class='styles_thumbnail__d2DAK styles_thumbnail__XBHZ_']//img | //div[contains(@class, 'styles_link')]//span[@class='lazyload-wrapper']/img")))
        icons = list(set(icons))
        if len(icons) > expected_number_of_icons:
            break
    
    icons = icons[:expected_number_of_icons]
    driver.close()
    

    当您达到所需的图标数量时选择停止的位置。显然,例如,如果您达到 210 个图标并且您只想要 200 个图标,您可以丢弃列表的最后 10 个元素

    【讨论】:

    • 它似乎获得了更多图标,但它跳过了一些,我想抓取前 20 个。
    • 是的,因为它会找到重复项。我编辑了答案以删除重复项。试试这个,如果它跳过一些检查它们是否有不同的路径,并将其他路径添加到原始路径,并带有 or 条件
    • 嗯,它仍然会得到随机图像。对我来说这很奇怪,这只发生在图像上
    • 随机图片是什么意思?它不只返回图标吗?它是否返回页面中的其他图像?
    • 不,我的意思是它会跳过一些图像。我想要前 20 个
    【解决方案2】:

    要打印 src 属性的值,您可以使用以下任一Locator Strategies

    • 使用css_selector

      print([my_elem.get_attribute("src") for my_elem in driver.find_elements_by_css_selector("span.lazyload-wrapper > img")])
      
    • 使用xpath

      print([my_elem.get_attribute("src") for my_elem in driver.find_elements_by_xpath("//span[@class='lazyload-wrapper']/img")])
      

    理想情况下,您必须为visibility_of_all_elements_located() 诱导WebDriverWait,您可以使用以下任一Locator Strategies

    • 使用CSS_SELECTOR

      driver.get('https://www.producthunt.com/topics/seo-tools?order=most-upvoted')
      print([my_elem.get_attribute("src") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "span.lazyload-wrapper > img")))])
      
    • 在一行中使用XPATH

      driver.get('https://www.producthunt.com/topics/seo-tools?order=most-upvoted')
      print([my_elem.get_attribute("src") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//span[@class='lazyload-wrapper']/img")))])
      
    • 注意:您必须添加以下导入:

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

    【讨论】:

    • 它仍然只返回前四个图标,我想获得所有第一组图标。如果我抓取 div,我会得到全部 20 个但不是图标的情况
    • @z3y50n 没关系 :) 看来你得到了一个公认的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2015-02-19
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多