使用Selenium和Python进行动态刮擦不会产生任何结果

问题描述 投票:0回答:3

我正在尝试使用硒抓取以下页面以获取所有工厂的名称:

https://bangladeshaccord.org/factories

我正在使用以下代码:

from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd


urlpage = "https://bangladeshaccord.org/factories"
print(urlpage)

driver = webdriver.Chrome(executable_path=r"C:\Users\filippo.sebastio\chromedriver.exe")

driver.get(urlpage)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
time.sleep(30)

results = driver.find_elements_by_xpath("//*[@id='factories']/div[3]/div/div/div[2]/div[3]/div[1]/div[2]/div[1]/div[2]/span[2]")
print('Number of results', len(results))

结果我得到

https://bangladeshaccord.org/factories

结果数1

为什么我只能得到一个结果?以及为什么我什至无法打印?

谢谢!

python selenium lazy-loading screen-scraping webdriverwait
3个回答
1
投票

原因是,您提供的xpath仅指向特定元素,因此仅得到一个结果。您应该使用上层括号div来获取所有结果框,然后获取其子div标签,最后是名称为h2的标签。问题仍然在于您将如何处理滚动负载?如果还有另一种更好的方法,在硒中进行自动滚动不是一个好主意。这是解决方案。检查网站,它向API发出GET / POST请求以获取所有数据,因此您甚至不必使用UI和Selenium来获取数据,您可以使用简单的GET / POST请求。这是第1页上使用默认过滤器进行工厂搜索的示例URL:

https://accord2.fairfactories.org/api/v1/factories?status=active,inactive,no%20brand,pending%20closure&designation=completed,ontrack,behindschedule,capnotfinalised,notfinalized,initialcompleted&progress=0,1,2,3,4,5,6,7,8,9&language=en&limit=20&format=json&page=1

这里的所有参数均来自用户界面中的过滤器,因此,如果要更改搜索结果,则需要自定义它们。将page参数用于下一页(在UI中滚动加载更多内容)。

现在您有了简单的GET / POST请求和要解析的JSON。

希望有所帮助。


0
投票

要检索结果数,您需要为visibility_of_all_elements_located()引入WebDriverWait,并且可以使用以下Locator Strategies

  • 代码块:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    options = webdriver.ChromeOptions()
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://bangladeshaccord.org/factories")
    driver.execute_script("arguments[0].scrollIntoView(true);",WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//h3[contains(., 'Accord Factories ')]"))))
    myLength = len(WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//p[./span[text()='Remediation Status:']]//preceding::h2[1]"))))
    print(myLength)
    driver.quit()
    

0
投票

如果要获取所有公司条目,则可以逐步向下滚动到页面的按钮。由于window.scrollTo在这里不起作用,所以我只是在这里[[* document.getElementById('page-body')。scrollTop = *。这样做将加载所有条目。

def scroll_to_bottom(driver): scroll_y = driver.execute_script("return document.getElementById('page-body').scrollTop") driver.execute_script("document.getElementById('page-body').scrollTop = {};".format(scroll_y+500)) new_scroll_y = driver.execute_script("return document.getElementById('page-body').scrollTop") while (scroll_y < new_scroll_y): driver.execute_script("document.getElementById('page-body').scrollTop = {};".format(new_scroll_y+500)) scroll_y = new_scroll_y new_scroll_y = driver.execute_script("return document.getElementById('page-body').scrollTop") time.sleep(2)
并且如其他答案所述,您必须使用其他选择器。然后,您的代码进行了一些更新(该代码向下滚动页面并最终打印出公司数量及其名称列表):

urlpage = "https://bangladeshaccord.org/factories" print(urlpage) webdriver.Chrome(executable_path=r"C:\Users\filippo.sebastio\chromedriver.exe") driver.get(urlpage) time.sleep(5) scroll_to_bottom(driver) results = driver.find_elements_by_class_name("sc-ldcLGC") print('Number of results', len(results)) for res in results: company = res.find_element_by_css_selector('h2.sc-cAJUJo') print(company.get_attribute("textContent"))

© www.soinside.com 2019 - 2024. All rights reserved.