¿Puedo combinar dos bloques de búsqueda 'findAll' en beautifulsoup, en uno?
-
22-07-2019 - |
Pregunta
¿Puedo combinar estos dos bloques en uno:
Editar: Cualquier otro método que no sea combinar bucles como lo hizo Yacoby en la respuesta.
for tag in soup.findAll(['script', 'form']):
tag.extract()
for tag in soup.findAll(id="footer"):
tag.extract()
También puedo hacer varios bloques en uno:
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()
o puede haber alguna expresión lambda en la que pueda verificar si está en la matriz o en cualquier otro método más simple.
Además, ¿cómo puedo encontrar etiquetas con la clase de atributo, ya que la clase es una palabra clave reservada:
EDITAR: esta parte se resuelve mediante la sopa.findAll (attrs = {'class': 'noprint'}):
for tag in soup.findAll(class="noprint"):
tag.extract()
Solución
Puede pasar funciones a .findall ()
de esta manera:
soup.findAll(lambda tag: tag.name in ['script', 'form'] or tag['id'] == "footer")
Pero puede que sea mejor construir primero una lista de etiquetas y luego iterar sobre ella:
tags = soup.findAll(['script', 'form'])
tags.extend(soup.findAll(id="footer"))
for tag in tags:
tag.extract()
Si desea filtrar por varios id
s, puede usar:
for tag in soup.findAll(lambda tag: tag.has_key('id') and
tag['id'] in ['footer', 'content', 'links']):
tag.extract()
Un enfoque más específico sería asignar una lambda al parámetro id
:
for tag in soup.findAll(id=lambda value: value in ['footer', 'content', 'links']):
tag.extract()
Otros consejos
No sé si BeautifulSoup puede hacerlo de manera más elegante, pero podría fusionar los dos bucles de esta manera:
for tag in soup.findAll(['script', 'form']) + soup.findAll(id="footer"):
tag.extract()
Puede encontrar clases como esta ( Documentation ):
for tag in soup.findAll(attrs={'class': 'noprint'}):
tag.extract()
La respuesta a la segunda parte de su pregunta es allí mismo en documentación :
Búsqueda por clase CSS
El argumento attrs sería una característica bastante oscura si no fuera por una cosa: CSS. Es muy útil buscar una etiqueta que tenga una determinada clase CSS, pero el nombre del atributo CSS, clase, también es una palabra reservada de Python.
Puede buscar por clase CSS con soup.find (" tagName " ;, {" class ": " cssClass "}), pero eso es mucho código para una operación tan común. En su lugar, puede pasar una cadena para atributos en lugar de un diccionario. La cadena se usará para restringir la clase 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)