Python, lxml和XPath - HTML表格解析

5

我是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


你能贴上源文件(或部分)和期望的结果吗?我不是Python专家,但我擅长XPath,我认为我可以帮助你。 - prostynick
把以下與編程相關的內容從英文翻譯成中文。僅返回翻譯後的文本:原始文檔在此處可用(僅限中歐時間06:00至22:00):http://tinyurl.com/yj4corh - user191131
预期结果:[['Premier', '05', 'name1'], [u'Deuxième', '13', 'name2']] - user191131
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]。

谢谢你的回答。但是在xpath末尾删除[0]会引发异常:AttributeError: 'list' object has no attribute 'xpath'。 - user191131
我不相信仅仅从语句末尾删除 [0] 就会导致那个错误。你肯定改变了其他东西,或者错误是在后面引发的。 - Robert Rossney
请原谅那个可怜的人,我必须承认我的Python技能很可能有所涉及...这是困扰我的实际代码片段:http://pastebin.com/m522b6970 - user191131

0
您需要使用循环来访问该行的数据,就像这样:
for row in data:  
    for col in row:
        print col

仅调用一次next()只能访问第一个项,这就是为什么你只看到了一列的原因。

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

更新:如果只需要第三行及其后面的行,请使用data[2:]


谢谢,嵌套循环和添加list()调用确实奏效了。但是它仍然不能与第二个xpath一起使用,而这正是我需要的(我猜)。 - user191131
我不清楚你为什么需要第二个xpath,可以看一下我回答的更新部分。 - interjay
我需要从第三行开始的所有表格内容,而第二个xpath只返回一行。当然,我已经按照您在更新中建议的做了,但我很想知道第二个xpath有什么问题,因为它会让我的代码在接下来的几天更加简洁。 - user191131

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接