python,lxml和xpath - html表解析

时间:2009-10-16 11:21:50

标签: python xpath lxml

我是lxml的新手,对python来说还是新手,无法找到以下解决方案:

我需要从第3行开始导入一些包含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]

任何人都知道一个奇特的解决方案,将第3行的所有数据都存入tbl并将其复制到数组中,以便可以将其处理成没有lxml依赖的模块吗?

先谢谢你的帮助,Alex

2 个答案:

答案 0 :(得分: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]让你搞砸了。

答案 1 :(得分:0)

您需要使用循环来访问行的数据,如下所示:

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

一旦调用next(),就会只访问第一项,这就是为什么你会看到一列。

请注意,由于生成器的性质,您只能访问它们一次。如果您将呼叫process_row(row)更改为list(process_row(row)),则生成器将转换为可重复使用的列表。

更新:如果您只需要第3行,请使用data[2:]