5

私はlxmlが初めてで、pythonがまったく初めてで、次の解決策を見つけることができませんでした:

3 つの列と行 3 から始まる行数が定義されていないいくつかのテーブルをインポートする必要があります。

いずれかの行の 2 列目が空の場合、この行は破棄され、テーブルの処理は中止されます。

次のコードは、テーブルのデータを正常に出力します (ただし、後でデータを再利用することはできません)。

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()

以下は、3 行目のみをインポートし、後続の行はインポートしません。

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

行3からすべてのデータをtblに取得し、それを配列にコピーして、lxml依存関係のないモジュールに処理できるようにするための優れたソリューションを知っている人はいますか?

助けてくれてありがとう、アレックス

4

2 に答える 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')]

の新しい値ごとにジェネレーターの新しいインスタンスを 1 回呼び出すだけで、生成されrowた最初の結果が返されます。

それがあなたの最初の問題です。あなたの2番目のものは、あなたが期待していることです:

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

3行目以降のすべての行を提供しますが、tbl3行目にのみ設定されています。への呼び出しxpath 、3 行目以降のすべての行を返します。[0]あなたを台無しにするのは最後です。

于 2009-10-16T21:04:38.943 に答える