¿Cómo puedo encontrar una tabla después de una cadena de texto usando BeautifulSoup en Python?

Estoy tratando de extraer datos de varias páginas web que no son uniformes en la forma en que muestran sus tablas. Necesito escribir código que busque una cadena de texto y luego ir a la tabla inmediatamente después de esa cadena de texto específica. Entonces quiero extraer los contenidos de esa tabla. Esto es lo que tengo hasta ahora:

from BeautifulSoup import BeautifulSoup, SoupStrainer import re html = ['

Table 1

1. row 1, cell 11. row 1, cell 2
1. row 2, cell 11. row 2, cell 2

Table 2

2. row 1, cell 12. row 1, cell 2
2. row 2, cell 12. row 2, cell 2
'] soup = BeautifulSoup(''.join(html)) searchtext = re.compile('Table 1',re.IGNORECASE) # Also need to figure out how to ignore space foundtext = soup.findAll('p',text=searchtext) soupafter = foundtext.findAllNext() table = soupafter.find('table') # find the next table after the search string is found rows = table.findAll('tr') for tr in rows: cols = tr.findAll('td') for td in cols: try: text = ''.join(td.find(text=True)) except Exception: text = "" print text+"|", print

Sin embargo, me sale el siguiente error:

  soupafter = foundtext.findAllNext() AttributeError: 'ResultSet' object has no attribute 'findAllNext' 

¿Hay una manera fácil de hacer esto usando BeautifulSoup?

El error se debe al hecho de que findAllNext es un método de objetos Tag , pero foundtext es un objeto ResultSet , que es una lista de tags o cadenas coincidentes. Puede recorrer cada una de las tags en el foundtext , pero dependiendo de sus necesidades, puede ser suficiente con el uso de find , que devuelve solo la primera etiqueta coincidente.

Aquí hay una versión modificada de su código. Después de cambiar el foundtext para usar soup.find , encontré y arreglé el mismo problema con la table . Modifiqué tu expresión regular para ignorar los espacios en blanco entre las palabras :

 from BeautifulSoup import BeautifulSoup, SoupStrainer import re html = ['

Table 1

1. row 1, cell 11. row 1, cell 2
1. row 2, cell 11. row 2, cell 2

Table 2

2. row 1, cell 12. row 1, cell 2
2. row 2, cell 12. row 2, cell 2

'] soup = BeautifulSoup(''.join(html)) searchtext = re.compile(r'Table\s+1',re.IGNORECASE) foundtext = soup.find('p',text=searchtext) # Find the first

tag with the search text table = foundtext.findNext('table') # Find the first

tag that follows it rows = table.findAll('tr') for tr in rows: cols = tr.findAll('td') for td in cols: try: text = ''.join(td.find(text=True)) except Exception: text = "" print text+"|", print

Esto produce:

 1. row 1, cell 1| 1. row 1, cell 2| 1. row 2, cell 1| 1. row 2, cell 2|