2016-12-31 4 views
1

Ich baue einen Scraper, der Preise von einem Dutzend verschiedener Websites kratzen muss.Warum funktioniert dieser xpath nicht mit PhantomJS?

Alle Websites verwenden JS, um den Preis anzuzeigen, also ging ich mit Selen, um die benötigten Daten zu kratzen.

Bevor ich mit dem Erstellen des Scraper begann, erstellte ich eine Liste von XPaths, die ich brauche, um das Preiselement für jede URL zu erhalten, die ich in einer externen Datei scrappte.

Ich habe jene XPath mit FireFox und Firebug, Hoàwever Ich erhalte eine errror, jedes Mal wenn ich versuche, dieses Element mit Selen (PhantomJS Treiber) zu erhalten:

selenium.common.exceptions.NoSuchElementException: Message: {"errorMessage":"Una 
ble to find element with xpath './div'","request":{"headers":{"Accept":"applicat 
ion/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"89 
","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:51048","User 
-Agent":"Python-urllib/2.7"},"httpVersion":"1.1","method":"POST","post":"{\"usin 
g\": \"xpath\", \"sessionId\": \"27f41b80-cf63-11e6-bbcc-13b1a315759a\", \"value 
\": \"./div\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"ele 
ment","directory":"/","path":"/element","relative":"/element","port":"","host":" 
","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/ 
element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/27f41b80-cf 
63-11e6-bbcc-13b1a315759a/element"}} 

Es scheint, dass mein XPath falsch ist, ich jedoch habe es mit anderen Plugins überprüft und es ist immer korrekt, wenn ich diesen XPath in Firefox teste.

Hier sind zwei verschiedene XPaths dass beide funktionieren sollte, (sie Firfox haben mit, aber nicht mit Selen):

"id('regular-hero')/div[3]/div[1]/div[2]/div/div[1]/div/div/span" 

"/html/body/div[2]/div[3]/div[1]/div[2]/div/div[2]/div/div/span/text()[1]" 

Und hier ist die Zielseite HTML-Code Here

Und hier ist der Code erhalten die elemnts Selen mit:

self.browser = wd.PhantomJS() 
for n in xrange(len(self.url_list)): 
    url = self.url_list[n] 
    provider = self.provider_list[n] 
    self.browser.get(url) 
    for plan in provider: 
     for hosting_plan in provider[plan]: 
      xpath = hosting_plan.values()[0] # Get the xpath of a plan 
      price_elem = self.browser.find_element_by_xpath("//*") 
      print price_elem 

self.browser.close() 

Alle Schleifen werden verwendet, um die JSON externe Datei zu durchlaufen, die die XPath-Liste halten.

Was ist los? Was soll ich versuchen? Kann mir lxml helfen (; da der HTML Code manchmal kaputt ist)?

+0

anzeigen 'HTML' Code des Zielelements – Andersson

+0

@Andersson Ich habe den Link zum HTML-Code der Zielseite hinzugefügt. –

+0

Sie könnten eine interaktive Selenium-Verschrottung für das problematische Objekt durchführen und den Code nach Python exportieren. Es sollte dich auf das hinweisen, was du falsch machst. – boardrider

Antwort

2

Nach angegebenen Link können Sie erforderliches Element entsprechen XPath mit folgenden:

//span[@class="term-price"] 

Wenn Ihr Element mit JavaScript erzeugt Sie einige Zeit für Element Aussehen warten müssen:

from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 

element = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, "//span[@class='term-price']"))) 
+0

Danke, aber warum andere XPaths nicht funktionieren? Sie sollten richtig sein, oder? Ich habe eine große Liste von XPaths und es würde zu viel Zeit brauchen, um es neu zu erstellen. –

+0

Ihre 'XPath's sind absolut. Dies bedeutet, dass sie fest und empfindlich gegenüber Änderungen in "DOM" sind. 'DOM' ist nicht konstant: Es könnte durch einige Ereignisse oder' JavaScript's ausgeführt werden. Sie sollten einen relativen 'XPath' finden, der alle Ihre Fälle ohne starke Bindung mit' DOM' abgleicht. – Andersson

+0

Aber meine Preiselemente werden durch JS erzeugt, beeinflusst das den XPath? –