2

私はほぼ間違いなくこれをひどく間違っています.私の問題の原因は私自身の無知ですが、Pythonのドキュメントと例を読んでも役に立ちません.

私はウェブスクレイピングをしています。私がスクレイピングしているページには、次の顕著な要素があります。

<div class='parent'>
   <span class='title'>
      <a>THIS IS THE TITLE</a>
   </span>
   <div class='copy'>
      <p>THIS IS THE COPY</p>
   </div>
</div>

私の目的は、親 div でグループ化された「タイトル」と「コピー」からテキスト ノードを取得することです。上記の例では、タプルを取得したいはずです('THIS IS THE TITLE', 'THIS IS THE COPY')

以下は私のコードです

## 'tree' is the ElementTree of the document I've just pulled 
xpath = "//div[@class='parent']"
filtered_html = tree.xpath(xpath)

arr = []

for i in filtered_html:

   title_filter = "//span[@class='author']/a/text()"  # xpath for title text
   copy_filter = "//div[@class='copy']/p/text()"      # xpath for copy text

   title = i.getroottree().xpath(title_filter)
   copy = i.getroottree().xpath(copy_filter)
   arr.append((title, copy))

私はn 個filtered_htmlの要素のリストになることを期待しています(それはそうです)。次に、その要素のリストを繰り返し処理し、それぞれを ElementTree に変換してタイトルを取得し、別の xpath 式でテキストをコピーしようとしています。したがって、反復ごとに、要素iのタイトル テキストを含む長さ 1 のリストであり、コピー テキストの対応するリストであると期待しています。titlecopy

最終的には、反復ごとに、 xpath式に一致するドキュメント内のすべての要素を含むtitle長さnのリストであり、コピーテキストの長さnの対応するリストです。title_filtercopy

今では、xpath と etree を使って何をしているのかを知っている人なら誰でも、私が恐ろしい、間違った、ばかげたことをしていることに気付くはずです。もしそうなら、彼らは私が代わりにこれをどのようにすべきか教えてもらえますか?

4

1 に答える 1

2

あなたの中心的な問題は、getroottree各テキスト要素で行っている呼び出しによって、ツリー全体で xpath を実行するようにリセットされることです。 getroottreeまさにそのように動作します - 呼び出した要素のルート要素ツリーを返します。その呼びかけを残せば、あなたが望むものを手に入れることができるように私には見えます.

個人的にはiterfind、メイン ループの要素ツリーでfindtextメソッドを使用し、結果の要素でメソッドを使用して、1 つのタイトルと 1 つのコピーのみを確実に受け取るようにします。

私の(テストされていない!)コードは次のようになります。

parent_div_xpath = "//div[@class='parent']"
title_filter = "//span[@class='title']/a"
copy_filter = "//div[@class='copy']/p"
arr = [(i.findtext(title_filter), i.findtext(copy_filter)) for i in tree.iterfind(parent_div_xpath)]

または、明示的な反復を完全にスキップすることもできます。

title_filter = "//div[@class='parent']/span[@class='title']/a/text()"
copy_filter = "//div[@class='parent']/div[@class='copy']/p/text()"
arr = izip(tree.findall(title_filter), tree.findall(copy_filter))

text()xpath からの呼び出しを削除してジェネレータ式に移動する必要があるかもしれませんが、それfindallを尊重するかどうかはわかりません。そうでない場合は、次のようになります。

arr = izip(title.text for title in tree.findall(title_filter), copy.text for copy in tree.findall(copy_filter))

また、親 div に複数のタイトル/コピー ペアが存在する可能性がある場合は、その xpath を微調整する必要があるかもしれません。

于 2013-05-24T16:07:19.420 に答える