2009-10-16 15 views
5

yo soy nuevo en LXML, bastante nuevo en Python y no pudo encontrar una solución a lo siguiente:pitón, lxml y XPath - html tabla de análisis sintáctico

Tengo que importar unas cuantas mesas con 3 columnas y un indefinido número de filas que comienzan en la fila 3.

Cuando la segunda columna de cualquier fila está vacía, esta fila se descarta y se interrumpe el procesamiento de la tabla.

El siguiente código imprime bien los datos de la tabla (pero no soy capaz de reutilizar los datos después):

from lxml.html import parse 

def process_row(row): 
    for cell in row.xpath('./td'): 
     print cell.text_content() 
     yield cell.text_content() 

def process_table(table): 
    return [process_row(row) for row in table.xpath('./tr')] 

doc = parse(url).getroot() 
tbl = doc.xpath("/html//table[2]")[0] 
data = process_table(tbl) 

Esto sólo se imprime la primera columna :(

for i in data: 
    print i.next() 

solamente la siguiente importar la tercera fila, y no la siguiente

tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0] 

Cualquiera conoce una solución elegante para obtener todos los datos de la fila 3 en tbl y copiarlo en una matriz para que pueda ser procesado en un módulo sin dependencia de lxml?

Gracias de antemano por su ayuda, Alex

+0

¿Podría pegar el documento fuente (o parte) y el resultado esperado? No soy un experto en python, pero estoy bien con xpath y creo que puedo ayudarte. – prostynick

+0

el documento fuente está disponible aquí (solo entre las 06h00 y las 22h00 CET): http://tinyurl.com/yj4corh – user191131

+0

resultado esperado: [['Premier', '05', 'name1'], [u'Deuxi \ xe8me ',' 13 ',' name2 ']] – user191131

Respuesta

0

Es necesario utilizar un bucle para acceder a los datos de la fila, así:

for row in data: 
    for col in row: 
     print col 

Llamando al lado() una vez como lo hizo sólo el accederá primer artículo, por lo que ves una columna.

Tenga en cuenta que debido a la naturaleza de los generadores, solo puede acceder a ellos una vez. Si cambió la llamada al process_row(row) en list(process_row(row)), el generador se convertiría a una lista que se puede reutilizar.

Actualización: Si necesita sólo la tercera fila y, tendrá que utilizar data[2:]

+0

Gracias, el bucle anidado y la adición de la llamada a la lista() hicieron el truco. Pero todavía no funciona con el segundo xpath, que es el que necesito (supongo) – user191131

+0

No me queda claro por qué necesita el segundo xpath, consulte la actualización de mi respuesta. – interjay

+0

Necesito todo el contenido de la tabla a partir de la fila 3, y el segundo xpath solo devuelve una fila. Por supuesto que hice lo que sugirió en su actualización, pero tengo curiosidad por saber qué está mal con el segundo xpath, ya que haría que mi código para los días siguientes fuera más limpio – user191131

2

Este es un generador:

def process_row(row): 
    for cell in row.xpath('./td'): 
     print cell.text_content() 
     yield cell.text_content() 

Estás llamando como si se pensaba que devuelve una lista. No es así Hay contextos en los que se comporta como una lista:

print [r for r in process_row(row)] 

pero eso es sólo porque un generador y una lista tanto exponen la misma interfaz para for bucles. Se utiliza en un contexto en el que se evalúa sólo una vez, por ejemplo .:

return [process_row(row) for row in table.xpath('./tr')] 

sólo llama a una nueva instancia del generador una vez para cada nuevo valor de row, volviendo el primer resultado producido.

Ese es su primer problema. Su segunda es que usted está esperando:

tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0] 

para darle la tercera y todas las filas posteriores, y sólo para la configuración de tbl a la tercera fila. Bueno, la llamada a xpathes devolviendo la tercera y todas las filas subsiguientes. Es el [0] al final que te está haciendo perder el pelo.

+0

Gracias por su respuesta. Pero eliminar el [0] al final del xpath aumenta la excepción: AttributeError: el objeto 'list' no tiene ningún atributo 'xpath' – user191131

+0

No creo que simplemente eliminando el '[0]' del final de esa declaración haya provocado que error. Has cambiado algo más, o el error se plantea más tarde. –

+0

Perdona a esa pobre alma, tengo que admitir que mis habilidades con las pitones probablemente están involucradas ... Aquí está el fragmento de código real que me molesta: http://pastebin.com/m522b6970 – user191131

Cuestiones relacionadas