Estoy tratando de raspar http://www.co.jefferson.co.us/ ats / displaygeneral.do? sch = 000104 y obtener el "Nombre (s) del propietario" Lo que tengo funciona pero es realmente feo y no es lo mejor, estoy seguro, así que estoy buscando una mejor manera. Esto es lo que tengo:

soup = BeautifulSoup(url_opener.open(url))            
x = soup('table', text = re.compile("Owner Name"))
print 'And the owner is', x[0].parent.parent.parent.tr.nextSibling.nextSibling.next.next.next

El HTML relevante es

<td valign="top">
    <table border="1" cellpadding="1" cellspacing="0" align="right">
    <tbody><tr class="tableheaders">
    <td>Owner Name(s)</td>
    </tr>

    <tr>

    <td>PILCHER DONALD L                         </td>
    </tr>

    </tbody></table>
</td>

Wow, hay muchas preguntas sobre beautifulsoup, las revisé pero no encontré una respuesta que me ayudó, espero que esta no sea una pregunta duplicada

1
Vincent 30 nov. 2009 a las 02:46

3 respuestas

La mejor respuesta

( Editar : aparentemente el código HTML que publicó el OP yace; de hecho, no hay una etiqueta tbody que buscar, aunque se propuso incluirlo en ese HTML. Entonces, cambiar usar table en lugar de tbody).

Como puede haber varias filas de tabla que desee (por ejemplo, vea la URL del hermano a la que le da, con el último dígito, 4, cambiado a 5), sugiero un bucle como el siguiente:

# locate the table containing a cell with the given text
owner = re.compile('Owner Name')
cell = soup.find(text=owner).parent
while cell.name != 'table': cell = cell.parent
# print all non-empty strings in the table (except for the given text)
for x in cell.findAll(text=lambda x: x.strip() and not owner.match(x)):
  print x

Esto es razonablemente robusto para cambios menores en la estructura de la página: después de ubicar la celda de interés, coloca en bucle a sus padres hasta que encuentra la etiqueta de la tabla, luego sobre todas las cadenas navegables dentro de esa tabla que no están vacías (o solo espacios en blanco), excluyendo el encabezado owner.

5
Benjamin 17 feb. 2014 a las 16:19

Esta es una ligera mejora, pero no pude encontrar la manera de deshacerme de los tres padres.

x[0].parent.parent.parent.findAll('td')[1].string
1
Mark Byers 30 nov. 2009 a las 00:08

Esta es la respuesta de Aaron DeVore del grupo de discusión Beautifulsoup: Funciona bien para mí.

soup = BeautifulSoup(...)
label = soup.find(text="Owner Name(s)")

Necesita Tag.string para llegar a la cadena de nombre real

name = label.findNext('td').string

Si está haciendo un montón de ellos, incluso puede buscar una lista de comprensión.

names = [unicode(label.findNext('td').string) for label in
soup.findAll(text="Owner Name(s)")]
3
Vincent 30 nov. 2009 a las 20:23