2016-04-21 1 views
1

Ich habe versucht, die Daten einer Website zu verschrotten und bis zu einem gewissen Grad gelingt mir mein Ziel. Aber, es gibt ein Problem, dass die Webseite, die ich verwerfen möchte, mehrere HTML-Tabellen darin hat. Wenn ich jetzt mein Programm ausführe, ruft es nur die Daten der ersten Tabelle in der CSV-Datei ab und ruft nicht die anderen Tabellen ab. Mein Java-Klassencode ist wie folgt.Wie Daten von mehreren HTML-Tabellen durch Web-Scrapping in Java abgerufen werden

public static void parsingHTML() throws Exception { 
     //tbodyElements = doc.getElementsByTag("tbody"); 
     for (int i = 1; i <= 1; i++) { 

      Elements table = doc.getElementsByTag("table"); 

      if (table.isEmpty()) { 
       throw new Exception("Table is not found"); 
      } 

      elements = table.get(0).getElementsByTag("tr"); 

      for (Element trElement : elements) { 
       trElement2 = trElement.getElementsByTag("tr"); 
       tdElements = trElement.getElementsByTag("td"); 
       File fold = new File("C:\\convertedCSV9.csv"); 
       fold.delete(); 
       File fnew = new File("C:\\convertedCSV9.csv"); 
       FileWriter sb = new FileWriter(fnew, true); 
       //StringBuilder sb = new StringBuilder(" "); 
       //String y = "<tr>"; 

       for (Iterator<Element> it = tdElements.iterator(); it.hasNext();) { 

        //Element tdElement1 = it.next(); 
        //final String content2 = tdElement1.text(); 
        if (it.hasNext()) { 
         sb.append("\r\n"); 

        } 
        for (Iterator<Element> it2 = trElement2.iterator(); it.hasNext();) { 
         Element tdElement2 = it.next(); 
         final String content = tdElement2.text(); 

         //stringjoiner.add(content); 
         //sb.append(formatData(content)); 
         if (it2.hasNext()) { 

          sb.append(formatData(content)); 
          sb.append(" , "); 

         } 
         if (!it.hasNext()) { 
          String content1 = content.replaceAll(",$", " "); 
          sb.append(formatData(content1)); 
          //it2.next(); 

         } 

        } 

        System.out.println(sb.toString()); 
        sb.flush(); 
        sb.close(); 

       } 
       System.out.println(sampleList.add(tdElements)); 

      } 
     } 
    } 

Was ich analysieren, ist, dass es eine Schleife gibt, die nur tr tds überprüft. Nach der ersten Tabelle gibt es also ein Stylesheet auf der HTML-Seite. Kann sein, wegen der Artblattschleife zu brechen. Ich denke, das ist der Grund, warum es zur nächsten Tabelle geht.

PS: Hier ist der Link, den ich http://www.mufap.com.pk/nav_returns_performance.php?tab=01

+0

Wie wäre es mit Ihrer Schleife, die Sie zwingt, nur auf einen Tisch zu schauen? 'für (int i = 1; i <= 1; i ++) {' – csmckelvey

+0

wenn ich es auf 'i <= 2 oder i <= 5' erhöhe, wird es die gleiche Tabelle für zwei Mal oder welche Nummer ich geschrieben habe. –

+0

Weil Sie die Tabelle hart codiert haben, die Sie betrachten möchten. 'elements = table.get (0) .getElementsByTag (" tr ");' Egal, wie oft Sie die Schleife durchlaufen, Sie sehen immer nur die erste Tabelle in der Sammlung. – csmckelvey

Antwort

1

Schrott versuche, was Sie gerade am Anfang des Codes tun wird nicht funktionieren:

// loop just once, why 
for (int i = 1; i <= 1; i++) { 
    Elements table = doc.getElementsByTag("table"); 

    if (table.isEmpty()) { 
     throw new Exception("Table is not found"); 
    } 
    elements = table.get(0).getElementsByTag("tr"); 

Hier können Sie Schleife nur einmal, lesen Sie alle table Elemente und dann alle tr Elemente für die ersten Tabelle verarbeiten, die Sie finden. Selbst wenn Sie mehr als einmal eine Schleife durchlaufen würden, würden Sie immer die erste table verarbeiten.

Sie müssen alle table Elemente iterieren, z.

for(Element table : doc.getElementsByTag("table")) { 
    for (Element trElement : table.getElementsByTag("tr")) { 
     // process "td"s and so on 
    } 
} 

bearbeiten Da Sie Probleme mit dem Code oben mit, hier ist ein gründlicheres Beispiel. Beachten Sie, dass ich Jsoup bin mit dem HTML zu lesen und zu analysieren (Sie hat nicht angegeben, was Sie verwenden)

Document doc = Jsoup 
       .connect("http://www.mufap.com.pk/nav_returns_performance.php?tab=01") 
       .get(); 

for (Element table : doc.getElementsByTag("table")) { 
    for (Element trElement : table.getElementsByTag("tr")) { 
     // skip header "tr"s and process only data "tr"s 
     if (trElement.hasClass("tab-data1")) { 

      StringJoiner tdj = new StringJoiner(","); 
      for (Element tdElement : trElement.getElementsByTag("td")) { 
       tdj.add(tdElement.text()); 
      } 

      System.out.println(tdj); 
     } 
    } 
} 

Dadurch werden alle Daten Zellen verketten und Druck (die die Klasse mit tab-data1). Sie müssen es noch ändern, um in Ihre CSV Datei zu schreiben.

Hinweis: in meinen Tests diese Prozesse 21 table s, 243 tr s und 2634 td s.

+0

Vielen Dank für Ihre Antwort. Ihr Code funktioniert, aber immer noch gibt es ein Problem, dass es zuerst 16 Tabellen von der Seite überspringt und den Rest bringt. –

+0

@AhmedTalha fügte meiner Antwort ein weiteres Beispiel hinzu – nyname00