web-dev-qa-db-fra.com

Comment trouver des éléments par classe

Je ne parviens pas à analyser les éléments HTML avec l'attribut "class" à l'aide de Beautifulsoup. Le code ressemble à ceci

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div["class"] == "stylelistrow"):
        print div

Je reçois une erreur sur la même ligne "après" la fin du script.

File "./beautifulcoding.py", line 130, in getlanguage
  if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
   return self._getAttrMap()[key]
KeyError: 'class'

Comment puis-je me débarrasser de cette erreur?

332
Neo

Vous pouvez affiner votre recherche pour ne trouver que ces divs avec une classe donnée en utilisant BS3:

mydivs = soup.findAll("div", {"class": "stylelistrow"})
547
Klaus Byskov Pedersen

De la documentation:

À partir de Beautiful Soup 4.1.2, vous pouvez effectuer une recherche par classe CSS à l'aide de l'argument de mot-cléclass_:

soup.find_all("a", class_="sister")

Ce qui dans ce cas serait:

soup.find_all("div", class_="stylelistrow")

Cela fonctionnerait aussi pour:

soup.find_all("div", class_="stylelistrowone stylelistrowtwo")
224
jmunsch

Mise à jour: 2016 Dans la dernière version de beautifulsoup, la méthode 'findAll' a été renommée 'find_all'. Lien vers la documentation officielle

List of method names changed

Par conséquent, la réponse sera

soup.find_all("html_element", class_="your_class_name")
45
overlord

Spécifique à BeautifulSoup 3:

soup.findAll('div',
             {'class': lambda x: x 
                       and 'stylelistrow' in x.split()
             }
            )

Trouvera tous ceux-ci:

<div class="stylelistrow">
<div class="stylelistrow button">
<div class="button stylelistrow">
15
FlipMcF

Une solution simple serait:

soup = BeautifulSoup(sdata)
for each_div in soup.findAll('div',{'class':'stylelist'}):
    print each_div

Assurez-vous de prendre le boîtier de findAll, ce n'est pas findall

15
Konark Modi

Comment trouver des éléments par classe

Je ne parviens pas à analyser les éléments HTML avec l'attribut "class" à l'aide de Beautifulsoup.

Vous pouvez facilement trouver par classe, mais si vous voulez trouver par intersection de deux classes, c'est un peu plus difficile,

De la documentation (soulignement ajouté):

Si vous souhaitez rechercher des balises qui correspondent à au moins deux classes CSS , vous devez utiliser un sélecteur CSS:

css_soup.select("p.strikeout.body")
# [<p class="body strikeout"></p>]

Pour être clair, ceci sélectionne uniquement les balises p qui sont à la fois barrées et classe de corps.

Pour rechercher l'intersection de quelconque dans un ensemble de classes (pas l'intersection, mais l'union), vous pouvez donner une liste à l'argument de mot clé class_ (comme de 4.1.2):

soup = BeautifulSoup(sdata)
class_list = ["stylelistrow"] # can add any other classes to this list.
# will find any divs with any names in class_list:
mydivs = soup.find_all('div', class_=class_list) 

Notez également que findAll a été renommé de camelCase en plus Pythonic find_all.

9
Aaron Hall

Sélecteurs CSS

première classe, premier match

soup.select_one('.stylelistrow')

liste des correspondances

soup.select('.stylelistrow')

classe composée (c'est-à-dire ET une autre classe)

soup.select_one('.stylelistrow.otherclassname')
soup.select('.stylelistrow.otherclassname')

Espaces dans les noms de classe composés, par ex. class = stylelistrow otherclassname sont remplacés par ".". Vous pouvez continuer à ajouter des classes.

liste des classes (OU - correspond à celui qui est présent

soup.select_one('.stylelistrow, .otherclassname')
soup.select('.stylelistrow, .otherclassname')

bS4 4.7.1 +

Classe spécifique dont innerText contient une chaîne

soup.select_one('.stylelistrow:contains("some string")')
soup.select('.stylelistrow:contains("some string")')

Classe spécifique qui a un certain élément enfant, par ex. Balise a

soup.select_one('.stylelistrow:has(a)')
soup.select('.stylelistrow:has(a)')
5
QHarr

Essayez de vérifier si la div a d'abord un attribut de classe, comme ceci:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
    if "class" in div:
        if (div["class"]=="stylelistrow"):
            print div
4
Mew

Cela me permet d’accéder à l’attribut class (sur beautifulsoup 4, contrairement à ce que dit la documentation). KeyError est une liste renvoyée et non un dictionnaire.

for hit in soup.findAll(name='span'):
    print hit.contents[1]['class']
3
Stgltz

À partir de BeautifulSoup 4+,

Si vous avez un nom de classe unique, vous pouvez simplement passer le nom de la classe en tant que paramètre comme:

mydivs = soup.find_all('div', 'class_name')

Ou si vous avez plusieurs noms de classe, il suffit de passer la liste des noms de classe en tant que paramètre tel que:

mydivs = soup.find_all('div', ['class1', 'class2'])
2
Shivam Shah

Cela a fonctionné pour moi:

for div in mydivs:
    try:
        clazz = div["class"]
    except KeyError:
        clazz = ""
    if (clazz == "stylelistrow"):
        print div
1
Larry Symms

ce qui suit a fonctionné pour moi

a_tag = soup.find_all("div",class_='full tabpublist')
1
Preetham D P

Cela devrait fonctionner:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div.find(class_ == "stylelistrow"):
        print div
0
Blue Sky