Могу ли я объединить два блока поиска findAll в beautifulsoup в один? - PullRequest
2 голосов
/ 01 декабря 2009

Могу ли я объединить эти два блока в один:

Редактировать: Любой другой метод, кроме объединения циклов, как Yacoby в ответ.

for tag in soup.findAll(['script', 'form']):
    tag.extract()

for tag in soup.findAll(id="footer"):
    tag.extract()

Также я могу объединить несколько блоков в один:

for tag in soup.findAll(id="footer"):
    tag.extract()

for tag in soup.findAll(id="content"):
    tag.extract()

for tag in soup.findAll(id="links"):
    tag.extract()

или, может быть, есть какое-то лямбда-выражение, где я могу проверить, есть ли в массиве, или любой другой более простой метод.

Также, как мне найти теги с атрибутом class, поскольку class является зарезервированным ключевым словом:

РЕДАКТИРОВАТЬ: эта часть решается с помощью soup.findAll (attrs = {'class': 'noprint'}):

for tag in soup.findAll(class="noprint"):
    tag.extract()

Ответы [ 4 ]

7 голосов
/ 01 декабря 2009

Вы можете передавать функции на .findall() следующим образом:

soup.findAll(lambda tag: tag.name in ['script', 'form'] or tag['id'] == "footer")

Но вам может быть лучше сначала создать список тегов, а затем повторить его:

tags = soup.findAll(['script', 'form'])
tags.extend(soup.findAll(id="footer"))

for tag in tags:
    tag.extract()

Если вы хотите фильтровать несколько id с, вы можете использовать:

for tag in soup.findAll(lambda tag: tag.has_key('id') and
                                    tag['id'] in ['footer', 'content', 'links']):
    tag.extract()

Более конкретным подходом будет присвоение лямбды параметру id:

for tag in soup.findAll(id=lambda value: value in ['footer', 'content', 'links']):
    tag.extract()
4 голосов
/ 01 декабря 2009

Я не знаю, сможет ли BeautifulSoup сделать это более элегантно, но вы можете объединить два цикла следующим образом:

for tag in soup.findAll(['script', 'form']) + soup.findAll(id="footer"):
    tag.extract()

Вы можете найти такие классы ( Документация ):

for tag in soup.findAll(attrs={'class': 'noprint'}):
    tag.extract()
0 голосов
/ 26 января 2018
links = soup.find_all('a',class_='external') ,we can pass class_ to filter based on class values

from bs4 import BeautifulSoup
from urllib.request import urlopen

with urlopen('http://www.espncricinfo.com/') as f:
    raw_data= f.read()
    soup= BeautifulSoup(raw_data,'lxml')
    # print(soup)
    links = soup.find_all('a',class_='external')
    for link in links:
        print(link)
0 голосов
/ 01 декабря 2009

Ответ на вторую часть вашего вопроса: прямо здесь в документации :

Поиск по классу CSS

Аргумент attrs был бы довольно неясной особенностью, если бы не одно: CSS. Очень полезно искать тег, который имеет определенный класс CSS, но имя атрибута CSS, class, также является зарезервированным словом Python.

Вы можете выполнять поиск по классу CSS с помощью soup.find ("tagName", {"class": "cssClass"}), но это достаточно много кода для такой распространенной операции. Вместо этого вы можете передать строку для attrs вместо словаря. Строка будет использоваться для ограничения класса CSS.

from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup("""Bob's <b>Bold</b> Barbeque Sauce now available in 
                   <b class="hickory">Hickory</b> and <b class="lime">Lime</a>""")

soup.find("b", { "class" : "lime" })
# <b class="lime">Lime</b>

soup.find("b", "hickory")
# <b class="hickory">Hickory</b>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...