【问题标题】:Searching nested tags with BeautifulSoup使用 BeautifulSoup 搜索嵌套标签
【发布时间】:2021-12-11 14:28:24
【问题描述】:

我正在尝试使用 selenium 和 python 中的 ecommerce website 解析 html,以便从产品标题中获得关注 text:

“电源插座 220V 32A IP44”和“34.60”

问题: 我的变量 productCardTitle 和 productPriceValue 得到空值。

这是我的 html:

<ul class="products-cards products-cards--view-grid grid">
    <li data-uid="210a10d0-4976-4c94-9ab4-0e7d38459c02" class="products-cards__item product-card">
        <div class="product-card__top">...</div> 
        <div class="product-card__content">...</div> 
        <div class="product-card__title-wrapper">
            <h3 class="product-card__title">
                <a href="/catalog/Electric-outlet-220V-32A-IP44">
                    Electric outlet 220V 32A IP44
                </a>
            </h3>
        </div> 
        ...                             
        <div class="product-card__bottom">
            <p class="product-card__price product-price product-price--small">...</p>
            <p class="product-card__price product-price">
                <span class="visually-hidden">Price:</span> 
                <span class="product-price__value">34.60</span> 
                <span class="product-price__currency">...</span> 
        ...
    </li>
</ul>

这是我在 python 中的代码:

productCards = soup.find_all('li', class_="products-cards__item product-card")
for productCard in productCards:
    productCardTitle = productCard.find_all('h3', class_="product-card__title")
    for product in productCardTitle:
        title = product.findChildren('a')[0].string.strip()
        print(title) 

    productPriceValue = productCard.find_all('span', class_="product-price__value")
    for product in productPriceValue:
        price = product.string.strip()
        print(price)

如果有人可以帮助我解决这个问题,我将不胜感激。

【问题讨论】:

  • 空是什么意思?您的代码适用于您的示例。
  • 我的意思是它实际上是空的。 Н我们的代码返回 [{'title': '', 'price': ''}]
  • 正如@Corralien 提到的,发布的html 一切都很好,也许还有另一个问题(动态提供的内容),所以请提供您尝试抓取的url。
  • 如何使用requests 或 Selenium 获取 html 页面?
  • 你说得对,很抱歉,发布的 html 一切正常。我会进一步查找错误。

标签: python html python-3.x parsing beautifulsoup


【解决方案1】:

也许,你想收集解析后的数据:

data = []
productCards = soup.find_all('li', class_="products-cards__item product-card")
for productCard in productCards:
    productCardTitle = productCard.find_all('h3', class_="product-card__title")
    for product in productCardTitle:
        title = product.findChildren('a')[0].string.strip()

    productPriceValue = productCard.find_all('span', class_="product-price__value")
    for product in productPriceValue:
        price = product.string.strip()
        
    data.append({'title': title, 'price': float(price)})

输出:

>>> data
[{'title': 'Electric outlet 220V 32A IP44', 'price': 34.6}]

【讨论】:

    【解决方案2】:

    不确定出了什么问题,您的结果是空的。用selenium 和requests 尝试过,两者都提供验证信息。

    无论如何 - 它不需要那么多循环来获取信息,让我们看看如何使它更精简。

    像这样选择所有卡片:

    soup.select('li.product-card')
    

    在结果集上迭代一次并创建list 的dicts:

    [
        {'title': card.h3.get_text(strip=True), 
         'price': card.select_one('span.product-price__value').get_text()
        } 
    
        for card in soup.select('li.product-card')
    ] 
    

    示例(硒)

    from bs4 import BeautifulSoup
    from selenium import webdriver
    
    driver = webdriver.Chrome('YOUR PATH TO CHROME')
    driver.get('https://shop-aventa.ru/search?q=+%D0%A0%D0%B0%D0%B7%D1%8A%D0%B5%D0%BC+220+')
    
    soup=BeautifulSoup(driver.page_source, 'html.parser')
    
    data = [
            {'title': card.h3.get_text(strip=True), 
             'price': card.select_one('span.product-price__value').get_text()
            } 
        
            for card in soup.select('li.product-card')
            ] 
    
    data
    

    示例(请求)

    import requests
    from bs4 import BeautifulSoup
    
    headers ={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
    }
    
    r =requests.get('https://shop-aventa.ru/search?q=+%D0%A0%D0%B0%D0%B7%D1%8A%D0%B5%D0%BC+220+')
    soup=BeautifulSoup(r.content, 'html.parser')
    
    data = [
            {'title': card.h3.get_text(strip=True), 
             'price': card.select_one('span.product-price__value').get_text()
            } 
        
            for card in soup.select('li.product-card')
            ] 
    
    data
    

    输出

    [{'title': 'Разъем 220 ЭКФ (Розетка 233), 63А, IP67', 'price': '934.60'}, {'title': 'Разъем 220 ЭКФ (Розетка 223), 32А, IP44', 'price': '286.00'}, {'title': 'Разъем 220 ЭКФ (Вилка 023), 32А, IP44', 'price': '239.40'}, {'title': 'Разъем 220 ЭКФ (Розетка 123), 32А, IP44', 'price': '342.80'}, {'title': 'Разъем 220 ЭКФ (Розетка 213), 16А, IP44', 'price': '200.70'}, {'title': 'Разъем 220 ЭКФ (Розетка 113), 16А, IP44', 'price': '269.70'}, {'title': 'Разъем 220 ЭКФ (Вилка 013), 16А, IP44', 'price': '161.50'}, {'title': 'Разъем 220 ЭКФ (Розетка 413), 16А, IP44', 'price': '269.20'}, {'title': 'Разъем 220В DKC 32А 220В, 2P+E, наст. IP44', 'price': '595.50'}, {'title': 'Разъем 220 ИЭК (Вилка 513), 16А, IP44, MAGNUM', 'price': '533.58'}, {'title': 'Разъем 220 ИЭК (Вилка 033), 63А, IP67, MAGNUM', 'price': '1 727.41'}, {'title': 'Разъем 220 ИЭК (Розетка 223), 32А, IP 44', 'price': '348.21'}, {'title': 'Разъем 220 ИЭК (Розетка 113), 16А, IP44, MAGNUM', 'price': '427.15'}, {'title': 'Разъем 220 ИЭК (Розетка 133), 63А, IP67, MAGNUM', 'price': '2 607.28'}, {'title': 'Разъем 220 ИЭК (Розетка 233), 63А, IP44', 'price': '2 051.63'}, {'title': 'Разъем 220 ИЭК (Вилка 023), 32А, IP44, MAGNUM', 'price': '362.05'}, {'title': 'Разъем 220 ИЭК (Розетка 113), 16А, IP 44', 'price': '330.47'}, {'title': 'Разъем 220 ИЭК (Вилка 023), 32А, IP 44', 'price': '291.02'}, {'title': 'Разъем 220 ИЭК (Розетка 213), 16А, IP44, MAGNUM', 'price': '341.92'}, {'title': 'Разъем 220 ИЭК (Вилка 013), 16А, IP 44', 'price': '200.54'}, {'title': 'Разъем 220 ИЭК (Вилка 033), 63А, IP54', 'price': '1 460.27'}, {'title': 'Разъем 220 ИЭК (Розетка скрытая 413), 16А, IP44', 'price': '350.79'}, {'title': 'Разъем 220 ИЭК (Розетка 133), 63А, IP54', 'price': '2 069.92'}, {'title': 'Разъем 220 ИЭК (Розетка 423), 32А, IP44, MAGNUM', 'price': '567.41'}]
    

    【讨论】:

    • 非常感谢@HedgeHog。不幸的是,我不能把你的答案放在“这个答案很有用”之上,因为我没有声誉。我还想说我的错误是使用soup=BeautifulSoup(driver.page_source, 'html5lib) 而不是soup=BeautifulSoup(driver.page_source, 'html.parser')
    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 2020-12-04
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 2018-03-12
    相关资源
    最近更新 更多