首页 > 解决方案 > 是否可以在一行代码中搜索多个容器?

问题描述

我有一个刮板,可以为产品刮一页。每个容器都以相同的方式设置,但它们被分组为几个不同的 s。我可以为每一类容器编写代码和循环,但我认为为所有容器在线编写会更清晰。这可能吗?

除了类名和我正在抓取的文本之外,四个类中的每一个的 HTML 代码都是相同的。它看起来像这样:

<tr class="product">

        <td>
        </td>
        <td>
            <a href="LINK">COMPANY NAME
        </td>
        <td data-order="PRODUCT NUMBER">
                            <div class="productnum">PRODUCT NUMBER</div>
                                        <img src="BRAND LOGO">
        </td>
        <td>

                CATEGORIES TEXT
        </td>

下一堂课将是:

<tr class="productGold">

        <td>
        </td>
        <td>
            <a href="LINK">COMPANY NAME
        </td>
        <td data-order="PRODUCT NUMBER">
                            <div class="productnum">PRODUCT NUMBER</div>
                                        <img src="BRAND LOGO">
        </td>
        <td>

                CATEGORIES TEXT
        </td>

...等等。

目前,我使用以下代码行来获取特定类中的所有产品:

containers = page_soup.findAll("tr",{"class":"productGold"})

然后我编写循环并将其导出到 csv。然后我对四个类中的每一个重复一遍:

{"class":"productGold"}), {"class":"productSilver"}), " 
{"class":"productBronze"}), and {"class":"product"})

我可以编写一行代码来查找所有类中的所有产品,然后遍历页面一次,而不是:

containers = page_soup.findAll("tr",{"class":"productGold"})

product_names = []
product_numbers = []
categories = []

with open('My-File.csv','w') as f:
    csv_out = csv.writer(f)
    for container in containers:
            product_name = container.a.text
            product_number = container.div.text
            category = container.select_one('td:nth-of-type(4)').text.strip() 

            product_names.append(product_name)
            proudct_numbers.append(product_number)
            categories.append(category)

            csv_out.writerow([product_name, product_number, category])

然后:

containers = page_soup.findAll("tr",{"class":"productSilver"})

product_names = []
product_numbers = []
categories = []

with open('My-File_1.csv','w') as f:
    csv_out = csv.writer(f)
    for container in containers:
            product_name = container.a.text
            product_number = container.div.text
            category = container.select_one('td:nth-of-type(4)').text.strip() 

            product_names.append(product_name)
            proudct_numbers.append(product_number)
            categories.append(category)

            csv_out.writerow([product_name, product_number, category])

那么对于{"class":"productBronze"}) and {"class":"product"})?

我想我可以在这一行做到这一点:

containers = page_soup.findAll("tr",{"class":"productGold"})

但我没有让它工作。任何帮助将不胜感激。

标签: pythonweb-scrapingbeautifulsoup

解决方案


使用正则表达式它将找到与产品相关的所有类。

import re
containers = page_soup.findAll("tr",class_=re.compile('product'))

或者您可以使用lamda功能

containers = page_soup.findAll(lambda tag:tag.name == "tr" and [tag.attrs=='class'.startswith('product')])

推荐阅读