2016-06-29 14 views
2

Ich arbeite an einem Projekt für meinen IT-Job, bei dem ich einen Scraper mit Scrapy/XPath schreiben muss, um einen relativ einfachen Datensatz von einer ziemlich einfachen HTML-Seite zu erhalten. Ich habe alles so funktionieren lassen, wie ich es möchte, mit Ausnahme von einigen kursiven Texten (die Website, die für ein Sprachausbildungsprogramm gekratzt wird und es gibt viele kursiv gedruckte Stellen in diesem speziellen Textfeld), die nicht angezeigt werden.Wie formatierter Text in XPath?

Unten finden Sie den Code I erfolgreich verwendet haben, bevor die kursiv gedruckten Ausgabe kam:

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

ich die folgende Rückkehr für "print rawTitles" erhalten:

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

Was ich will, ist so etwas wie dies:

[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>'] 

Wenn die wörtliche HTML-Tags können nicht in die Ausgabe aufgenommen werden, würde ich bei l Ost wie der Klartext, der enthalten sein soll. Leere Räume, in denen Wörter einfach sein sollten, scheinen nicht das Beste zu sein, was ich tun kann.

Weiß jemand, was ich versuchen möchte? Lassen Sie es mich wissen, wenn ich nicht genügend Informationen zur Verfügung stelle. Danke im Voraus.

EDIT: Hier ist ein Beispiel für einen Tabelleneintrag, von dem ich brauche zu extrahieren Info:

<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

Können Sie Beispiel-HTML-Eingabe bereitstellen? –

+0

Ich habe gerade einige hinzugefügt; lass es mich wieder wissen, wenn es nicht viel hilft. – jah

Antwort

1

Schauen wir uns an verschiedenen Extraktionsmuster in scrapy Schale, den Aufbau einer Selektor aus Ihrer Probe HTML:

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

Lassen Sie uns zuerst auf <h2 class="video"> Elemente (mit CSS-Selektoren) Schleife und extrahieren Sie eine Zeichenfolgendarstellung jeder Überschrift innerhalb der Schleife:

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

Wir verlieren die <i> Information.

Lasst uns versuchen, nur Textknoten bekommen (mit text() Knotentest):

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

Noch schlimmer als zuvor, wir sind Textknoten innerhalb nicht <i> Elemente bekommen. (In der Tat, text() wählt nur direkte Kinder Textknoten, nicht Kinder von Kindern)

Lassen Sie uns versuchen mit .//, a.k.eine ./descendant-or-self::node()/ Abkürzung

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

Nicht viel besser als string() XPath der Verwendung. Jetzt

, lassen Sie uns node() Knotentest verwenden, erfassen Elemente und Textknoten:

>>> 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>'] 

Das ist besser, aber wir haben diese <img>-Tags, die Sie vielleicht nicht wollen. Lassen Sie uns also nur Textknoten und <i> s Pick:

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

Möglicherweise möchten Sie aus jeder Rubrik einen einzelnen String erhalten. So verwenden Python join() ist eine Option:

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

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

Mit text() auf einem Element namens Sie nur die Top-Level erhalten Textknoten, während Sie wollen nach unten gehen, um jedes Kind Element als auch, verwenden .//text():

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

Sie dann die Elemente einer rawTitles Liste mit str.join() beitreten können, aber ich würde empfehlen, Blick in Item Loaders und Eingabe- und Ausgabe-Prozessoren - es gibt Join() Prozessor, der in diesem Fall geeignet wäre.

Oder Paul Rat in Kommentaren verwenden string() XPath-Funktion folgen:

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

Ich würde empfehlen, XPaths 'string()' -Funktionen 'rawTitles = response.xpath ('string (// h2 [@ class =" video "])') zu verwenden. Extract_first()' –

+0

@paultrmbrth ah, guter Punkt, würde viel einfacher sein. Vielen Dank. – alecxe

+0

Ich werde diese Lösungen in ein paar Minuten versuchen - ich hatte bereits versucht, "text()" durch ".// text()" zu ersetzen und bekam genau das gleiche Ergebnis, aber es klingt, als ob es sowieso komplizierter ist. Danke euch beiden und ich melde mich mit Ergebnissen zurück. – jah

Verwandte Themen