2016-06-29 10 views
2

私はかなり簡単なHTMLページからかなり簡単なデータセットを得るためにScrapy/XPathを使ってスクレーパーを書く必要がある私のIT仕事のためのプロジェクトに取り組んでいます。イタリック体のテキストを除いて、私はそれが望むようにすべての作業をしてきました。(傷ついたウェブサイトは、語学教育プログラムのためのものであり、この特定のテキストフィールドにイタリック体のインスタンスがたくさんあります。以下は書式付きテキストをXPathに含めるにはどうすればよいですか?

斜体の問題が思い付いた前に、私は正常に使用しているコードです:

rawTitles = [] 
for sel in response.xpath('//h2[@class="video"]'): 
    rawTitle = sel.xpath('text()').extract() 
    rawTitles.append(rawTitle[0]) 
print rawTitles 

私は「印刷rawTitles」について、次のリターンを得る:私が欲しいもの

[u'\n', u'\nVariations in Making ', u'\nMaking ', u'\nCommon Rice and Meat Dishes', u'\nRumens and '] 

のようなものですこれは、リテラルHTMLタグを出力に含めることができない場合

[u'\n<i>Mjadra</i>', u'\nVariations in Making <i>Mansaf</i>', u'\nMaking <i>Maqloobeh</i>', u'\nCommon Rice and Meat Dishes', u'\nRumens and <i>Mahashi</i>'] 

、私はLのだろう含まれる平文のように東。言葉がちょうど空白でなければならない空白は、私ができる最善のもののようには見えません。

私は何を試してみたいですか?十分な情報を提供していないかどうか教えてください。前もって感謝します。

編集:ここで私は情報を抽出する必要があり、そこからテーブルエントリの例です:text()

<td width="25%" valign="top" align="center"> 
<h2 class="video"><img src="content/pl_makingfood_mjadrah.jpg"  alt="Thumbnail image from video" width="160" height="120" /><br /><br /> 
<i>Mjadra</i></h2>  <p class="video">Video <br /> 

<a href="content/pl_makingfood_mjadrah.rm" class="main">real</a>&nbsp;&nbsp; 
<a href="content/pl_makingfood_mjadrah.mp4" class="main" target="_blank">mp4</a><br /><br /> 

Palestinian Arabic &amp; English <br /> 
<a href="content/pl_makingfood_mjadrah.doc" target="_blank" class="main"> doc </a>&nbsp; &nbsp; 
<a href="content/pl_makingfood_mjadrah.pdf" target="_blank" class="main"> pdf </a></p> 
</td> 
+0

サンプル入力HTMLを提供できますか? –

+0

私はいくつかを追加しました。それほど助けにならないなら、私にもう一度教えてください。 – jah

答えて

1

あなたのサンプルHTMLからセレクタを構築する、のがscrapyシェルで異なる抽出パターンを見てみましょう:

>>> import scrapy 
>>> t = '''<td width="25%" valign="top" align="center"> 
... <h2 class="video"><img src="content/pl_makingfood_mjadrah.jpg"  alt="Thumbnail image from video" width="160" height="120" /><br /><br /> 
... <i>Mjadra</i></h2>  <p class="video">Video <br /> 
... 
... <a href="content/pl_makingfood_mjadrah.rm" class="main">real</a>&nbsp;&nbsp; 
... <a href="content/pl_makingfood_mjadrah.mp4" class="main" target="_blank">mp4</a><br /><br /> 
... 
... Palestinian Arabic &amp; English <br /> 
... <a href="content/pl_makingfood_mjadrah.doc" target="_blank" class="main"> doc </a>&nbsp; &nbsp; 
... <a href="content/pl_makingfood_mjadrah.pdf" target="_blank" class="main"> pdf </a></p> 
... </td>''' 
>>> selector = scrapy.Selector(text=t, type="html") 

まず、<h2 class="video">要素を(CSSセレクタを使用して)ループし、ループ内の各見出しの文字列表現を抽出しましょう:

>>> for h2 in selector.css('h2.video'): 
...  print(h2.xpath('string()').extract()) 
... 
['\nMjadra'] 

<i>の情報が失われています。

はのは(text()ノードテスト付き)のみのテキストノードを取得してみましょう:以前より

>>> for h2 in selector.css('h2.video'): 
...  print(h2.xpath('text()').extract()) 
... 
['\n'] 

さらに悪いことに、私たちは<i>要素内のテキストノードを取得されていません。 (実際には、text()は子供の子供ではなく直接子供のテキストノードのみを選択します)

.//、a.kを試してみましょう。./descendant-or-self::node()/ショートカット:

>>> for h2 in selector.css('h2.video'): 
...  print(h2.xpath('.//text()').extract()) 
... 
['\n', 'Mjadra'] 

ないのXPathのstring()を使用するよりもはるかに良いです。

それでは、要素とテキストノードをキャプチャし、node()ノード・テストを使用してみましょう:良いでしょう

>>> for h2 in selector.css('h2.video'): 
...  print(h2.xpath('node()').extract()) 
... 
['<img src="content/pl_makingfood_mjadrah.jpg" alt="Thumbnail image from video" width="160" height="120">', '<br>', '<br>', '\n', '<i>Mjadra</i>'] 

が、我々はあなたが望んでいないことがあり、これらの<img>のタグを持っています。それでは、唯一のテキストノードと<i> Sを選んでみましょう:

>>> for h2 in selector.css('h2.video'): 
...  print(h2.xpath('./node()[self::text() or self::i]').extract()) 
... 
['\n', '<i>Mjadra</i>'] 
>>> 

あなたは各見出しのうち、単一の文字列を取得することができます。したがって、Pythonのjoin()を使用することはオプションです:

>>> for h2 in selector.css('h2.video'): 
...  print("".join(h2.xpath('./node()[self::text() or self::i]').extract())) 
... 

<i>Mjadra</i> 
>>> 
1

要素で呼び出さあなたはあなたがしたい一方で唯一トップレベルのテキストノードにを取得.//text()を使用するだけでなく、すべての子要素に下る:

rawTitles = response.xpath('//h2[@class="video"]//text()').extract() 

あなたはその後、str.join()rawTitlesリストの項目に参加することができますが、私が推薦しますItem Loadersと入力と出力のプロセッサーを調べると、この場合にはJoin()プロセッサーが適しています。

あるいは、string() XPath関数を使用し、コメントでパウロのアドバイスに従うこと:

rawTitles = response.xpath('string(//h2[@class="video"])').extract_first() 
+0

XPathの 'string()'関数を使用することをお勧めします。rawTitles = response.xpath( 'string(// h2 [@ class = "video"])')extract_first() ' –

+0

@paultrmbrthああ、良い点ですはるかに簡単です。ありがとう。 – alecxe

+0

私はこれらの解決策を数分で試してみます - 私はすでに "text()"を ".// text()"に置き換えようとしましたが、まったく同じ結果を得ました。両方おかげさまで、結果を報告します。 – jah

関連する問題