首页 > 解决方案 > 根据各种参数选择div

问题描述

我是网络抓取的新手,并试图用某些参数抓取特定网站。现在,我想获取满足以下条件的 div:

  1. 我想排除div其中具有确定性class的内容。

  2. 我想排除div没有class属性的。

  3. 我想包含div一个特定id的并且没有任何类或除了被忽略的类列表之外的类。

现在,到目前为止,我已经使用以下代码完成了 2 个条件:

classToIgnore = ["class1", "class2", "class3"]

for div in soup.find_all('div', class_=lambda x: x in classToIgnore):
    div.decompose()

for div in soup.find_all('div', class_=False):   
    div.decompose() 

find_all()现在,我不知道如何在此处添加第三个条件,并且如果可能的话,我还想在单个语句中执行所有 3 个过滤器。

标签: pythonpython-3.xweb-scrapingbeautifulsoup

解决方案


在处理如此复杂的情况时,将其包装在单独的函数中始终是最佳实践。BeautifulSoup 允许你使用一个函数作为过滤器

from bs4 import BeautifulSoup, Tag
html = """
<div class="c1"></div>
<div class="c1" id="myid">
    <div class="c1"></div>
</div>
<div class="c2"></div>
<div class="c3" id="myid"></div>
<div class="c4"></div>
<div></div>
<div id="myid"></div>
"""

soup = BeautifulSoup(html, 'html.parser')
classToIgnore = ["c1", "c2"]

# Using decompose to solve cases where
# unwanted classes comes inside wanted classes
for div in soup.find_all('div', class_=lambda x: x in classToIgnore):
    div.decompose()


def my_filter(ele):
    if (
        isinstance(ele, Tag) and
        ele.name == 'div' and
        ele.get('id') == 'myid' and not ele.get('class') or
        ele.get('class')
    ):
        return True


print(soup.find_all(my_filter))

输出

[<div class="c3" id="myid"></div>, <div class="c4"></div>, <div id="myid"></div>]

推荐阅读