【问题标题】:Selenium webscrape won't work after different methods tried尝试不同方法后,Selenium webscrape 将不起作用
【发布时间】:2021-10-13 23:16:48
【问题描述】:

我要抓取的确切页面是:https://www.footasylum.com/page/search/?term=Nike%20Air%20Force%201

Selenium 目前通过找到搜索栏并使用它可以很好地工作,上面的页面就是显示的内容,我现在想检索所有产品名称和价格,我尝试了很多方法但它不起作用。

方法一,XPATH:

product = driver.find_elements_by_xpath('//td[@class="listing-productname"]')
product_list = []
for p in range(len(product)):
product_list.append(product[p].text)
print(product_list)

当我尝试打印 product_list 或产品本身时,这不起作用...它返回为空 []。

方法二,类名:

product = driver.find_elements_by_class_name('listing-productname')
print(product)

也不返回任何内容,只是 []

方法3,类名,但另一种:

product = driver.find_elements_by_class_name('data-width')
print(product)

也不返回任何内容。

方法3,类名,但另一个类:

shoe_name = driver.find_elements_by_class_name('listing-productname')
print(shoe_name)

什么也没有。

不确定现在要做什么,因为我觉得我开始使用所有可用的元素,无论我使用 XPATH 还是类名,我仍然没有返回任何内容,只是 []。

另外 - 没有错误,根据终端,代码运行良好,只是没有打印任何东西,我认为这意味着它显然没有找到任何东西?

有谁知道我做错了什么并能够帮助我?我也想检索产品价格并以同样的方式挣扎。

谢谢!

【问题讨论】:

    标签: python html selenium selenium-webdriver web-scraping


    【解决方案1】:

    你的方法 1,xpath 没有定位 web 元素,所以你得到一个空列表。

    然而方法 2 是正确的,但这需要调整:

    product = driver.find_elements_by_class_name('listing-productname')
    for p in product:
        print(p.text)
    

    应该打印 20 个项目名称,因为 listing-productname 这代表 20 个网络元素。

    或者我宁愿用这段代码来抓取所有的名称和价格:

    names = []
    price = []
    for name in driver.find_elements(By.XPATH, "//span[@data-nq-product-name]"):
      names.append(name.text)
      price.append(name.find_element_by_xpath("//span[@data-nq-product-name]/../../following-sibling::div").text)
    
    print(names, price)
    

    PS:您没有收到任何错误,因为您使用的是find_elements,它会返回一个网络元素列表或一个空列表。

    更新 1:

    driver = webdriver.Chrome(driver_path)
    driver.maximize_window()
    driver.implicitly_wait(30)
    driver.get("https://www.footasylum.com/page/search/?term=Nike%20Air%20Force%201")
    wait = WebDriverWait(driver, 20)
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul.cookie-container i"))).click()
    names = []
    price = []
    i = 1
    for name in driver.find_elements(By.XPATH, "//span[@data-nq-product-name]"):
      names.append(name.text)
      price.append(name.find_element_by_xpath(f"(//span[@data-nq-product-name]/../../following-sibling::div)[{i}]").text)
      i = i + 1
    
    print(names, price)
    

    进口:

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

    输出:

    ['Air Force 1 Low SOS Trainer', 'Air Force 1 LV8 Trainer', 'Junior Air Force 1 Low Trainer', 'Junior Air Force 1 GS ‘Bred’ Low Trainer', 'Air Force 1 Low Trainer', "Air Force 1 LV8 'Brooklyn Splatter' Trainer", 'Junior Air Force 1 Low Trainer', 'Infant Air Force 1 Low Trainer', 'Junior Air Force 1 Crater Flyknit Trainer', 'Infant Air Force 1 Low Trainer', 'Womens Air Force 1 Low Trainer', 'Air Force 1 Mid Trainer', "Junior Air Force 1 Low 'Space Jam' Trainer", 'Air Force 1 LV8 Trainer', "Air Force 1 '07 x Space Jam Trainer", 'Nursery Air Force 1 Low Trainer', 'Crib Air Force 1 Trainer', 'Nursery Air Force 1 Low Trainer', 'Womens Air Force 1 Pixel Trainer', 'Nursery Air Force 1 Low Trainer'] ['£99.99', '£99.99', '£57.99', '£54.99', '£99.99', '£99.99', '£64.99', '£44.99', '£69.99', '£44.99', '£99.99', '£109.99', '£64.99', '£99.99', '£109.99', '£39.99', '£27.99', '£37.99', '£109.99', '£39.99']
    
    Process finished with exit code 0
    

    【讨论】:

    • 谢谢,这非常有用。我复制了您确切的第二个代码 sn-p,但是 print(names, price) 仍然返回两个空列表作为 [ ] [ ],我该如何解决这个问题? @cruisepandey。无论如何,我是否可以让它返回包含名称和价格的清单?除非我误解了什么,否则我认为 .append() 代码会添加到这些中。
    • 你确定你复制了正确的代码吗?
    • 我想是的。我写过:names = [] price = [] for name in driver.find_elements(By.XPATH, "//span[@data-nq-product-name]"): names.append(name.text) price.append(name.find_element_by_xpath("//span[@data-nq-product-name]/../../following-sibling::div").text) print(names, price)@cruisepandey
    • 而不是names.append(name.text),试试print(name.text),看看有没有打印出来?
    • 仍然没有:/我不知道为什么。也许我错过了一些明显的东西?没有错误,只是为空或代码编译正常。
    【解决方案2】:

    试试这个代码:

    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('https://www.footasylum.com/page/search/?term=Nike%20Air%20Force%201')
    p = driver.page_source
    from bs4 import *
    soup = BeautifulSoup(p, 'html.parser')
    [[x.text.strip() for x in x.findAll('div')] for x in soup.find('div', {'data-nq-property-value':'search'}).findAll('div', class_='listing-text')]
    

    根据您的评论:

    soup.find('div', {'data-nq-property-value':'search'}) 将返回包含搜索结果的 div。每个搜索结果都有一个唯一的 div,其类名称为 listing-text,其中包含您要查找的文本 brand name, shoes model and price。此 div 包含三个没有类的 div,由 .findAll('div') 检索。然后将每个 div 的文本条带化,最后将所有三个项目放在一个列表中。 这可以重写如下:

    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('https://www.footasylum.com/page/search/?term=Nike%20Air%20Force%201')
    p = driver.page_source
    from bs4 import *
    soup = BeautifulSoup(p, 'html.parser')
    results_text = soup.find('div', {'data-nq-property-value':'search'}).findAll('div', class_='listing-text')
    for item in results_text:
        texts = item.findAll('div')
        brand = texts[0].text.strip()
        name = texts[1].text.strip()
        price = texts[2].text.strip()
        print([brand, name, price])
    

    结果应该是:

    [['Nike', 'Air Force 1 Low SOS Trainer', '£99.99'],
     ['Nike', 'Infant Air Force 1 Low Trainer', '£44.99'],
     ['Nike', 'Air Force 1 LV8 Trainer', '£99.99'],
     ['Nike', 'Air Force 1 Low Trainer', '£99.99'],
     ['Nike', 'Junior Air Force 1 GS ‘Bred’ Low Trainer', '£54.99'],
     ['Nike', 'Junior Air Force 1 Low Trainer', '£57.99'],
     ['Nike', 'Infant Air Force 1 Low Trainer', '£44.99'],
     ['Nike', 'Junior Air Force 1 Low Trainer', '£64.99'],
     ['Nike', 'Junior Air Force 1 Crater Flyknit Trainer', '£69.99'],
     ['Nike', "Womens Air Force 1 '07 Trainer", '£99.99'],
     ['Nike', "Junior Air Force 1 Low 'Space Jam' Trainer", '£64.99'],
     ['Nike', 'Womens Air Force 1 Pixel Trainer', '£109.99'],
     ['Nike', 'Womens Air Force 1 Low Trainer', '£89.99'],
     ['Nike', 'Womens Air Force 1 Trainer', '£99.99'],
     ['Nike', 'Air Force 1 Mid Trainer', '£109.99'],
     ['Nike', 'Air Force 1 LV8 Trainer', '£99.99'],
     ['Nike', 'Nursery Air Force 1 Low Trainer', '£37.99'],
     ['Nike', 'Nursery Air Force 1 Low Trainer', '£39.99'],
     ['Nike', 'Nursery Air Force 1 Low Trainer', '£39.99'],
     ['Nike', 'Crib Air Force 1 Trainer', '£27.99']]
    

    【讨论】:

    • 我想我可能更喜欢这种方法(结合硒和 bs4,而不是只使用纯硒)。你能向我解释一下你的代码 sn-p 的最后一行到底是做什么的吗? @idar
    • 我刚刚进行了编辑以回答您的问题。
    猜你喜欢
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    相关资源
    最近更新 更多