2016-09-05 1 views
1

Inhaltsübersicht: Mein Code geht an eine craigslist ad URL. Es extrahiert die versteckten Telefonnummern im Anzeigenhauptteil. Der Code funktioniert für viele URLs außer dem, den ich in den Code aufgenommen habe. (BTW, können Sie kopieren und meinen Code ausführen, ohne zusätzlichen Code zu schreiben.)Warum funktioniert Selen getAttribute ("href") nicht?

Problem: Die getAttribute("href") kehren ein null nur für diese URL. Warum ? Wie behebe ich das?

Code:

import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.chrome.ChromeDriver; 

import java.util.ArrayList; 
import java.util.List; 

public class Temp { 
    private static final WebDriver browser = new ChromeDriver(); 
    private static WebDriver temp_browser = new ChromeDriver(); 

    /*The code fails only for this url.*/ 
    private static String url = "https://sfbay.craigslist.org/pen/apa/5764613878.html"; 

    public static String phone_btns_xpath = "//section[@id='postingbody']//*[contains(.,'show contact info')]"; 
    public static By phone_btns_loc = By.xpath(phone_btns_xpath); 

    public static void main(String[] args) { 
     browser.get(url); 
     List<String> phones = reveal_hidden_phone_numbers(temp_browser); 
     temp_browser.close(); 
     System.out.println(phones); 
    } 

    public static List<String> reveal_hidden_phone_numbers(WebDriver temp_browser) { 
     List<WebElement> phone_btns = browser.findElements(phone_btns_loc); 
     List<String> phones = null; 
     String text = null; 

     if (phone_btns.size() > 0) { 
      WebElement phone_btn_0 = phone_btns.get(0); 
      System.out.println(phone_btn_0.getAttribute("innerHTML")); 

      String url = phone_btn_0.getAttribute("href"); 
      temp_browser.get(url); 
      text = temp_browser.findElement(By.tagName("body")).getText(); 

      for (WebElement phone_btn : phone_btns) { 
       phone_btn.click(); 
      } 

      phones = extract_phone_numbers(text); 
     } 
     return phones; 
    } 

    public static List<String> extract_phone_numbers(String text) { 
     List<String> output = new ArrayList<String>(); 
     output.add("PHONE ;)"); 
     return output; 
    } 

} 

Stapelüberwachung:

<a href="/fb/sfo/apa/5764613878" class="showcontact" title="click to show contact info" rel="nofollow">show contact info</a> 

Exception in thread "main" java.lang.NullPointerException: null value in entry: url=null 
    at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:33) 
    at com.google.common.collect.SingletonImmutableBiMap.<init>(SingletonImmutableBiMap.java:39) 
    at com.google.common.collect.ImmutableBiMap.of(ImmutableBiMap.java:49) 
    at com.google.common.collect.ImmutableMap.of(ImmutableMap.java:70) 
    at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:316) 
    at com.craigslist.Temp.reveal_hidden_phone_numbers(Temp.java:38) 
    at com.craigslist.Temp.main(Temp.java:23) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 
+0

Was hat System.out.println (phone_btn_0.getAttribute ("innerHTML")); Ausgabe? Versuchen Sie Folgendes, um zu sehen, welche Attribute verfügbar sind. System.out.println (((JavascriptExecutor) -Browser) .executeScript ("return arguments [0] .attributes", phone_btn_0)); Element); – MikeJRamsey56

Antwort

1

Als ich in Ihrem vorgesehen stacktrace diese Zeile System.out.println(phone_btn_0.getAttribute("innerHTML")); aus dem Code gedruckt, um den inneren HTML von phone_btn_0 Element da : -

<a href="/fb/sfo/apa/5764613878" class="showcontact" title="click to show contact info" rel="nofollow">show contact info</a>

Das bedeutet, Sie versuchen, href Attribut auf falsches Element zu erhalten. Es ist auf Elternelement anstelle des tatsächlichen Verbindungselements, in dem href Attribut nicht existiert, deshalb erhalten Sie null.

Angenommen, Sie href Attributwert aus diesem Druckverbindungselement HTML erhalten mögen, so sollten Sie versuchen href Attributwert auf dem Kind-Element von phone_btn_0 wie unten zu bekommen: -

WebElement phone_btn_0 = phone_btns.get(0); 
System.out.println(phone_btn_0.getAttribute("innerHTML")); 

String url = phone_btn_0.findElement(By.tagName("a")).getAttribute("href"); 

Herausgegeben: - Sie können auch zunächst fix in xpath nur a Element zu finden, anstatt alle * mit dem gleichen Code sowie: -

public static String phone_btns_xpath = "//section[@id='postingbody']//a[contains(.,'show contact info')]"; 
+1

Oder ich könnte meinen XPath reparieren, um nach 'a' anstatt nach * oder nach allen Elementen zu suchen. Ich dachte, dass ich das richtig verstanden habe. – testerjoe2

+0

Ja, Sie haben Recht, Sie können es auch anfänglich in xpath reparieren, um nur einen statt '*' als 'public static String zu finden phone_btns_xpath =" // section [@ id = 'postingbody'] // a [enthält (., 'Kontaktinformationen anzeigen')] " –

0

Sie können .to String-Methode wie folgt verwenden .. ..s funktioniert für mich String url = phone_btn_0.findElement (By.tagName ("a")). GetAttribute ("href"). ToString();