2010-05-14 7 views
41

Nun, ich versuche ziemlich genau herauszufinden, wie man Informationen von einer Webseite holt und sie in mein Programm bringt (in Java).Wie scanne ich eine Webseite (oder Seite) nach Informationen und bringe sie in mein Programm?

Zum Beispiel, wenn ich die genaue Seite kenne, von der ich Informationen möchte, der Einfachheit halber eine Best Buy Artikelseite, wie würde ich die entsprechenden Informationen bekommen, die ich von dieser Seite brauche? Wie der Titel, Preis, Beschreibung?

Wie würde dieser Prozess überhaupt heißen? Ich habe keine Ahnung, dass ich überhaupt anfangen sollte, das zu erforschen.

Edit: Okay, ich bin ein Test für die JSoup läuft (die von BalusC posted on), aber ich erhalte immer diese Fehlermeldung:

Exception in thread "main" java.lang.NoSuchMethodError: java.util.LinkedList.peekFirst()Ljava/lang/Object; 
at org.jsoup.parser.TokenQueue.consumeWord(TokenQueue.java:209) 
at org.jsoup.parser.Parser.parseStartTag(Parser.java:117) 
at org.jsoup.parser.Parser.parse(Parser.java:76) 
at org.jsoup.parser.Parser.parse(Parser.java:51) 
at org.jsoup.Jsoup.parse(Jsoup.java:28) 
at org.jsoup.Jsoup.parse(Jsoup.java:56) 
at test.main(test.java:12) 

ich habe Apache Commons

+1

Sie habe ein Problem mit LinkedList, weil LinkedList.peekFirst in Java 1.6 erschienen ist und du anscheinend ein Ohr verwendest Lier-Version – zamza

+2

Dieser Prozess wird häufig als "screen scraping" bezeichnet und wird verwendet, wenn eine API (wie SOAP) nicht verfügbar ist, aber eine Web-GUI ist. Es bedeutet, dass Ihre Anwendung sich als Webbrowser ausgeben und die HTML-Seiten (mehr oder weniger) manuell parsen muss. Ich schlage vor, dass Sie eine der unten aufgeführten APIs in Betracht ziehen, die einen Großteil der Analyse automatisieren. –

Antwort

83

Verwenden Sie einen HTML-Parser wie Jsoup. Dies hat meine Präferenz über die other HTML parsers available in Java seit es supports wie CSS selectors. Außerdem implementiert seine Klasse, die eine Liste von Knoten darstellt, Elements, implementiert Iterable, so dass Sie in einer enhanced for loop darüber iterieren können (es gibt also keine Notwendigkeit, mit den ausführlichen Klassen Node und NodeList Klassen im durchschnittlichen Java-DOM-Parser zu kämpfen).

Hier ist ein Grund Kickoff Beispiel (nur die latest Jsoup JAR file in Classpath setzen):

package com.stackoverflow.q2835505; 

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.select.Elements; 

public class Test { 

    public static void main(String[] args) throws Exception { 
     String url = "https://stackoverflow.com/questions/2835505"; 
     Document document = Jsoup.connect(url).get(); 

     String question = document.select("#question .post-text").text(); 
     System.out.println("Question: " + question); 

     Elements answerers = document.select("#answers .user-details a"); 
     for (Element answerer : answerers) { 
      System.out.println("Answerer: " + answerer.text()); 
     } 
    } 

} 

Wie Sie vielleicht schon erraten haben, diese druckt Ihre eigene Frage und die Namen aller Beantworter.

+1

Wow, das ist schön! Ich habe jedoch eine Frage, ich kopiere und klebte das nur, um einen Testlauf zu machen, aber ich bekomme immer diesen Fehler (siehe bearbeitete OP) – James

+2

@James: Dies erfordert mindestens Java 1.6 (welches bereits seit 3 ​​Jahren aus ist) . Die erwähnte ['LinkedList # peekFirst()'] (http://java.sun.com/javase/6/docs/api/java/util/LinkedList.html#peekFirst%28%29) Methode wurde in Java 1.6 eingeführt . Aktualisieren Sie Ihre JVM (JDK) oder konfigurieren Sie Ihre IDE (Eclipse?) Im Java 6-Kompatibilitätsmodus. – BalusC

+8

Wenn irgendwelche .NET Programmierer interessiert sind, habe ich jsoup nach .NET portiert: http://nsoup.codeplex.com/. Hoffe das hilft jedem. – GeReV

3

Sie kann einen HTML-Parser verwenden (viele nützliche Links hier: java html parser).

Der Prozess heißt "Website-Inhalt abrufen". Suchen Sie nach 'webcontent content java' für weitere Invertierungen.

-1

Schauen Sie in die cURL-Bibliothek. Ich habe es nie in Java verwendet, aber ich bin mir sicher, dass es Bindings dafür geben muss. Im Grunde werden Sie eine cURL-Anfrage an die Seite senden, die Sie "scrape" wollen. Die Anfrage gibt eine Zeichenfolge mit dem Quellcode an die Seite zurück. Von dort werden Sie Regex verwenden, um alle Daten aus dem Quellcode zu analysieren. Das ist im Allgemeinen, wie Sie es tun werden.

+3

[Regex nicht zum Analysieren von HTML verwenden] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). – BalusC

9

Dies wird als Screen Scraping bezeichnet, wikipedia hat diesen Artikel auf der spezifischen web scraping. Es kann eine große Herausforderung sein, da es da draußen ein paar hässliche, kaputte, kaputte HTML-Dateien gibt, die nicht für den Browser geeignet sind, also viel Glück.

1

Sie sollten sich wahrscheinlich den HTML-Code ansehen, um herauszufinden, ob Sie Zeichenketten finden können, die eindeutig und in der Nähe Ihres Textes sind. Dann können Sie Line/Char-Offsets verwenden, um zu den Daten zu gelangen.

Könnte in Java peinlich sein, wenn es keine XML-Klassen gibt, die denen in System.XML.Linq in C# ähneln.

4

Der Prozess selbst wird normalerweise "Scraping" genannt. Sie können einen Parser wie TagSoup verwenden, um die Seite zu bearbeiten, sobald Sie sie abgerufen haben.

4

Ich würde JTidy verwenden - es ist ähnlich wie JSoup, aber ich kenne JSoup nicht gut. JTidy verarbeitet beschädigtes HTML und gibt ein w3c-Dokument zurück, sodass Sie dieses als Quelle für XSLT verwenden können, um den Inhalt zu extrahieren, an dem Sie wirklich interessiert sind.Wenn Sie XSLT nicht kennen, können Sie auch JSoup verwenden, da das Document-Modell besser zu verwenden ist als w3c.

EDIT: Ein kurzer Blick auf die JSoup Website zeigt, dass JSoup tatsächlich die bessere Wahl ist. Es scheint CSS-Selektoren zu unterstützen, um Dinge aus dem Dokument zu extrahieren. Das kann viel einfacher sein als mit XSLT.

1

JSoup Lösung ist groß, aber wenn Sie extrahieren müssen nur etwas wirklich einfach es leichter sein, Regex zu verwenden oder String.indexOf

Wie andere haben bereits den Prozess genannt wird genannt

+0

Warum wäre es einfacher, Regex zu verwenden? Ich habe versucht, Regex und es kann wirklich nicht mit dem wirklichen Leben HTML umgehen und es ist möglicherweise gefährlich, Parse HTML zu verwenden. Jsoup ist eine Out-of-the-Box-Lösung, nur ein paar Zeilencodes und Sie tun, was immer Sie mit Ihrem HTML tun müssen. – newbie

+0

Beispiel für eine vereinfachte Darstellung - Stellen Sie sich vor, Sie möchten nur das Datum der Seitenerstellung extrahieren. Sie überprüfen also den HTML-Code und sehen etwas wie ' 07/07/07 '. Nun, dann würde ich String benutzen.indexOf oder einige meiner eigenen Dienstprogramme wie textBetween ("", ""). Ein zusätzlicher Vorteil ist, dass Sie nicht den gesamten HTML-Code analysieren müssen. Ich hatte Erfolg beim Extrahieren von Daten aus HTML mit einer eigenentwickelten StringScanner-Klasse mit Methoden wie moveBefore (String was), moveAfter (String was), getTextUpTo (String was), ... Es hängt alles davon ab, wie kompliziert dein Problem ist. – Anton

1

Sie könnten auch versuchen, jARVEST.

Es basiert auf einem JRuby DSL über eine reine Java-Engine, um Websites zu spider-scrape-transformieren.

Beispiel:

Suche alle Links innerhalb einer Webseite (wget und xpath sind Konstrukte der Sprache des jARVEST):

wget | xpath('//a/@href') 

In einem Java-Programm:

Jarvest jarvest = new Jarvest(); 
    String[] results = jarvest.exec(
    "wget | xpath('//a/@href')", //robot! 
    "http://www.google.com" //inputs 
); 
    for (String s : results){ 
    System.out.println(s); 
    }