Python: BeautifulSoup - obtenir une valeur d'attribut basée sur l'attribut de nom

91

Je veux imprimer une valeur d'attribut en fonction de son nom, prenons par exemple

<META NAME="City" content="Austin">

Je veux faire quelque chose comme ça

soup = BeautifulSoup(f) //f is some HTML containing the above meta tag
for meta_tag in soup('meta'):
    if meta_tag['name'] == 'City':
         print meta_tag['content']

Le code ci-dessus donne un KeyError: 'name', je pense que c'est parce que le nom est utilisé par BeatifulSoup, donc il ne peut pas être utilisé comme argument de mot-clé.

Ruth
la source

Réponses:

154

C'est assez simple, utilisez ce qui suit -

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('<META NAME="City" content="Austin">')
>>> soup.find("meta", {"name":"City"})
<meta name="City" content="Austin" />
>>> soup.find("meta", {"name":"City"})['content']
u'Austin'

Laissez un commentaire si quelque chose n'est pas clair.

le plus dur
la source
1
comment puis-je faire cela si je veux trouver toutes les instances, c'est-à-dire pour le moment, soup.find ("meta", {"name": "City"}) ['content'] donne le premier résultat, mais disons qu'il y en a eu un autre ligne dans la soupe qui était <META NAME = 'City "content =" San Francisco ">. Comment pourrais-je modifier le code pour obtenir" Austin "et" San Francisco "?
dépassé
1
Vieille question, mais voici une solution simple au cas où quelqu'un d' autre vient le chercher: soup.findAll("meta", {"name":"City"})['content']. Cela renverra toutes les occurrences.
Hannon César
comment puis-je obtenir la valeur d'un attribut spécifique? signifie que je n'ai que l'attribut ...
Phaneendra Charyulu Kanduri
27

theharshest a répondu à la question mais voici une autre façon de faire la même chose. De plus, dans votre exemple, vous avez NAME en majuscules et dans votre code, vous avez le nom en minuscules.

s = '<div class="question" id="get attrs" name="python" x="something">Hello World</div>'
soup = BeautifulSoup(s)

attributes_dictionary = soup.find('div').attrs
print attributes_dictionary
# prints: {'id': 'get attrs', 'x': 'something', 'class': ['question'], 'name': 'python'}

print attributes_dictionary['class'][0]
# prints: question

print soup.find('div').get_text()
# prints: Hello World
Délicieux
la source
La différence de casse est probablement intentionnelle car BeautifulSoup convertit les balises en minuscules par défaut. Dans ce cas: BeautifulSoup ('<META NAME = "City" content = "Austin">') renvoie <meta content = "Austin" name = "City" />
tuckermi
9

6 ans de retard à la fête, mais j'ai cherché comment extraire la valeur d'attribut de balise d' un élément html , donc pour:

<span property="addressLocality">Ayr</span>

Je veux "addressLocality". J'ai continué à être renvoyé ici, mais les réponses n'ont pas vraiment résolu mon problème.

Comment j'ai réussi à le faire finalement:

>>> from bs4 import BeautifulSoup as bs

>>> soup = bs('<span property="addressLocality">Ayr</span>', 'html.parser')
>>> my_attributes = soup.find().attrs
>>> my_attributes
{u'property': u'addressLocality'}

Comme il s'agit d'un dict, vous pouvez également utiliser keyset 'valeurs'

>>> my_attributes.keys()
[u'property']
>>> my_attributes.values()
[u'addressLocality']

Espérons que cela aide quelqu'un d'autre!

ron_g
la source
8

Les travaux suivants:

from bs4 import BeautifulSoup

soup = BeautifulSoup('<META NAME="City" content="Austin">', 'html.parser')

metas = soup.find_all("meta")

for meta in metas:
    print meta.attrs['content'], meta.attrs['name']
BrightMoon
la source
7

La réponse de theharshest est la meilleure solution, mais pour votre information, le problème que vous rencontrez est lié au fait qu'un objet Tag dans Beautiful Soup agit comme un dictionnaire Python. Si vous accédez à la balise ['name'] sur une balise qui n'a pas d'attribut 'name', vous obtiendrez une KeyError.

Leonard Richardson
la source
1

On peut également essayer cette solution:

Pour trouver la valeur, qui est écrite dans l'étendue de la table

htmlContent


<table>
    <tr>
        <th>
            ID
        </th>
        <th>
            Name
        </th>
    </tr>


    <tr>
        <td>
            <span name="spanId" class="spanclass">ID123</span>
        </td>

        <td>
            <span>Bonny</span>
        </td>
    </tr>
</table>

Code Python


soup = BeautifulSoup(htmlContent, "lxml")
soup.prettify()

tables = soup.find_all("table")

for table in tables:
   storeValueRows = table.find_all("tr")
   thValue = storeValueRows[0].find_all("th")[0].string

   if (thValue == "ID"): # with this condition I am verifying that this html is correct, that I wanted.
      value = storeValueRows[1].find_all("span")[0].string
      value = value.strip()

      # storeValueRows[1] will represent <tr> tag of table located at first index and find_all("span")[0] will give me <span> tag and '.string' will give me value

      # value.strip() - will remove space from start and end of the string.

     # find using attribute :

     value = storeValueRows[1].find("span", {"name":"spanId"})['class']
     print value
     # this will print spanclass
Ujjaval Moradiya
la source
1
If tdd='<td class="abc"> 75</td>'
In Beautifulsoup 

if(tdd.has_attr('class')):
   print(tdd.attrs['class'][0])


Result:  abc
Priyank Singhal
la source
1
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la façon et / ou pourquoi il résout le problème améliorerait la valeur à long terme de la réponse.
shaunakde