Puis-je combiner deux blocs de recherche 'findAll' dans beautifulsoup, en un seul?

StackOverflow https://stackoverflow.com/questions/1825187

  •  22-07-2019
  •  | 
  •  

Question

Puis-je combiner ces deux blocs en un seul:

Éditer: Toute autre méthode que la combinaison de boucles, comme le faisait Yacoby dans la réponse.

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

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

Puis-je également utiliser plusieurs blocs en un seul:

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()

ou peut-être y a-t-il une expression lambda où je peux vérifier si elle est dans un tableau ou dans une autre méthode plus simple.

Comment trouver des balises avec une classe d'attributs, car classe est un mot clé réservé:

EDIT: cette partie est résolue par la soupe.findAll (attrs = {'class': 'noprint'}):

for tag in soup.findAll(class="noprint"):
    tag.extract()
Était-ce utile?

La solution

Vous pouvez transmettre des fonctions à .findall () comme ceci:

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

Mais il serait peut-être préférable de créer d'abord une liste de balises, puis de la parcourir:

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

for tag in tags:
    tag.extract()

Si vous souhaitez filtrer plusieurs id , vous pouvez utiliser:

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

Une approche plus spécifique consisterait à affecter un lambda au paramètre id :

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

Autres conseils

Je ne sais pas si BeautifulSoup peut le faire de manière plus élégante, mais vous pouvez fusionner les deux boucles comme suit:

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

Vous pouvez trouver des classes comme celle-ci ( Documentation ):

for tag in soup.findAll(attrs={'class': 'noprint'}):
    tag.extract()

La réponse à la deuxième partie de votre question est à droite dans le documentation :

  

Recherche par classe CSS

     

L'argument attrs serait une fonctionnalité assez obscure si ce n'était pour une chose: CSS. Il est très utile de rechercher une balise ayant une certaine classe CSS, mais le nom de l’attribut CSS, class, est également un mot réservé Python.

     

Vous pouvez effectuer une recherche par classe CSS avec soup.find ("tagName", {, "class": "" cssClass "}), mais c'est beaucoup de code pour une opération aussi courante. Au lieu de cela, vous pouvez passer une chaîne pour attrs au lieu d'un dictionnaire. La chaîne sera utilisée pour restreindre la classe 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>
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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top