¿Hay alguna manera de obtener todos los valores de un determinado atributo?

Ejemplo:

<a title="title-in-a">
  <b title="title-in-b"> ... </b>
  <c title="title-in-c"> ... </c>
  <d name="i-dont-care"> ... </d>
</a>

¿Puedo obtener todos los títulos, incluso si están en etiquetas diferentes?

Resultado esperado:

['title-in-a', 'title-in-b', 'title-in-c']

Para obtener todos los títulos en <a>, sé que puedo hacer esto:

for item in soup.find_all('a'):
    print item['title']

Pero, ¿cómo hacerlo para todas las etiquetas, incluso sin saber las etiquetas?

4
klaus 10 may. 2019 a las 01:46

4 respuestas

La mejor respuesta

Utiliza un selector de atributos.

titles = [item['title'] for item in soup.select('[title]')]
2
QHarr 10 may. 2019 a las 03:55

Suponiendo que no haya ningún error en su código (lo que significa que las etiquetas <b> y <c> están encerradas dentro de la etiqueta <a>) entonces:

for i in soup4.find_all(title=True):
  print(i)

Producirá:

<a title="title-in-a">
<b title="title-in-b"> ... </b>
<c title="title-in-c"> ... </c>
...</a>
<b title="title-in-b"> ... </b>
<c title="title-in-c"> ... </c>

Si, por otro lado, cada etiqueta se cierra por separado, de modo que el código es:

<a title="title-in-a">...</a>
<b title="title-in-b"> ... </b>
<c title="title-in-c"> ... </c>

La salida es:

<a title="title-in-a">...</a>
<b title="title-in-b"> ... </b>
<c title="title-in-c"> ... </c>
3
Jack Fleeting 10 may. 2019 a las 00:22

Aquí está la solución para su caso de uso. Hay un método predeterminado llamado attrs que obtendrá todos los atributos como dict {'name': 'value'}

response = '''<a title="title-in-a">
  <b title="title-in-b"> ... </b>
  <c title="title-in-c"> ... </c>
  <d name="i-dont-care"> ... </d>
</a>'''
total_attributes = []
soup = BeautifulSoup(response,'lxml')
for tags in soup.find_all():
    attributes = tags.attrs
    #some filtering goes here 
    if attributes:
        required = list(attributes.values())
        total_attributes = total_attributes + required
print(total_attributes)

Puede esperar resultados como, también puede hacer el filtrado en el lugar resaltado.

['title-in-a', 'title-in-b', 'title-in-c', 'i-dont-care']
1
Dhamodharan 10 may. 2019 a las 12:58

Use la función python lambda para buscar el atributo de etiqueta title

from bs4 import BeautifulSoup

data='''<a title="title-in-a">
  <b title="title-in-b"> ... </b>
  <c title="title-in-c"> ... </c>
</a>'''

soup=BeautifulSoup(data,'html.parser')

for item in soup.find_all(lambda tag:[tag.attrs=='title']):
  print(item['title'])

Salida:

title-in-a
title-in-b
title-in-c
0
KunduK 10 may. 2019 a las 07:10