Выберите div в соответствии с различными параметрами - PullRequest
1 голос
/ 12 октября 2019

Я новичок в очистке веб-страниц и пытаюсь удалить конкретный веб-сайт с определенными параметрами. Теперь я хочу получить 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() 

Теперь я не знаю, как добавить здесь 3-е условие, а также хочу сделать все 3 фильтра в одном выражении find_all(), если это возможно.

Ответы [ 2 ]

1 голос
/ 12 октября 2019

При работе с такими сложными условиями всегда лучше обернуть его в отдельную функцию. 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>]
0 голосов
/ 12 октября 2019

Я мог пропустить некоторые случаи, поэтому, пожалуйста, попробуйте следующее с bs4 4.7.1 +, который использует: не для исключений или css And синтаксис. Примечание. Я изменил имена ваших классов в списке, чтобы они стали селекторами, добавив "."

from bs4 import BeautifulSoup as bs

classes_to_ignore = [".class1", ".class2", ".class3"]

html = '''
<div class="class1">a</div>
<div class="class2">b</div>
<div class="class3">c</div>
<div class="class4">d</div>
<div>e</div>
<div id="id1" class="class5">f</div>
<div id="id1">g</div>
<div id="id1" class="class1">h</div>
<div id="id1" class="class2">i</div>
'''

soup = bs(html, 'lxml')
ignore = ','.join(classes_to_ignore)
divs = soup.select(f"div[id='id1']:not({ignore}), div:not({ignore})[class]")
print(divs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...