Python、lxml 和 xpath - HTML 表格解析
我刚接触lxml,也刚开始学Python,遇到了一些问题,找不到解决办法:
我需要导入几个表格,每个表格有3列,行数不固定,从第三行开始。
如果任何一行的第二列是空的,这一行就会被丢弃,整个表格的处理也会停止。
下面的代码可以很好地打印出表格的数据(但我之后无法重复使用这些数据):
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)
这段代码只打印了第一列 :(
for i in data:
print i.next()
而这段代码只导入了第三行,而没有后面的行。
tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0]
有没有人知道一个好的方法,可以把第三行及其后的所有数据导入到tbl中,并复制到一个数组里,这样就可以在没有lxml依赖的情况下进行处理?
提前谢谢大家的帮助,Alex
2 个回答
0
你需要用一个循环来访问每一行的数据,像这样:
for row in data:
for col in row:
print col
你只调用一次next(),就只会得到第一项,所以你只看到一列数据。
要注意,由于生成器的特性,你只能访问它一次。如果你把调用 process_row(row)
改成 list(process_row(row))
,那么生成器就会被转换成一个可以重复使用的列表。
更新:如果你只需要从第三行开始的数据,可以用 data[2:]
。
2
这是一个生成器:
def process_row(row):
for cell in row.xpath('./td'):
print cell.text_content()
yield cell.text_content()
你在调用它的时候,以为它会返回一个列表。其实并不是。它在某些情况下表现得像一个列表:
print [r for r in process_row(row)]
但这只是因为生成器和列表在for
循环中使用时,展现出来的接口是一样的。使用它的场景如果只评估一次,比如:
return [process_row(row) for row in table.xpath('./tr')]
每次新的row
值时,都会调用生成器的新实例,只返回第一个结果。
所以这是你的第一个问题。第二个问题是你期待:
tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0]
能给你第三行及之后的所有行,但它实际上只把tbl
设置为第三行。其实,调用xpath
确实返回了第三行及之后的所有行。问题出在最后的[0]
上,这让你困惑了。