Wie „Scan“ eine Website (oder Seite) für Informationen, und es in mein Programm zu bringen?

StackOverflow https://stackoverflow.com/questions/2835505

  •  26-09-2019
  •  | 
  •  

Frage

Nun, ich versuche so ziemlich um herauszufinden, wie Informationen von einer Webseite zu ziehen und es in mein Programm bringen (in Java).

Zum Beispiel, wenn ich die genaue Seite weiß ich info will aus, aus Gründen der Einfachheit eine Best Buy Artikelseite, wie würde ich die entsprechenden Informationen, die ich von dieser Seite muß weg erhalten? Wie der Titel, Preis, Beschreibung?

Was würde dieser Prozess auch genannt werden? Ich habe keine Ahnung, dies auch nur ansatz war zu erforschen.

Edit: Okay, ich bin ein Test für die JSoup läuft (der einen gepostet von BalusC), 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 haben

War es hilfreich?

Lösung

Verwenden Sie einen HTML-Parser wie Jsoup . Das hat meine Vorliebe über dem andere HTML verfügbar Parser in Java da es unterstützt jQuery wie CSS-Selektoren . Auch seine Klasse eine Liste von Knoten darstellt, Elements , implementiert Iterable , so dass Sie es in einem iterieren kann < a href = "http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html" rel = "noreferrer"> for-Schleife verbessert (es gibt also keine Notwendigkeit, Ärger mit ausführlichen Node und NodeList wie Klassen im Durchschnitt Java DOM-Parser).

Hier ist ein Grund Kickoff Beispiel (nur das setzen neueste Jsoup JAR-Datei in Classpath):

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.

Andere Tipps

Dies wird als Screen Scraping bezeichnet wird, hat wikipedia diesen Artikel auf der spezielleren Web-Scraping . Es kann eine große Herausforderung sein, weil es einige hässliche, Chaos-up, broken-if-not-for-Browser-Klugheit HTML gibt, so viel Glück.

würde ich jtidy - es ist simlar zu JSoup, aber ich weiß nicht JSoup gut. Jtidy Griffe HTML und gibt ein w3c Dokument gebrochen, so dass Sie diese als Quelle XSLT verwenden, um die Inhalte, die Sie interessiert sind wirklich zu extrahieren. Wenn Sie XSLT nicht kennen, dann könnte man genauso gut gehen mit JSoup, wie das Dokument Modell ist schöner zu arbeiten als mit w3c.

EDIT: Ein kurzer Blick auf die JSoup Website zeigt, dass JSoup tatsächlich die bessere Wahl sein kann. Es scheint, zum Extrahieren von Material aus dem Dokument CSS-Selektoren aus der Box zu unterstützen. Dies kann viel einfache Arbeit mit als in XSLT zu bekommen.

Sie können einen HTML-Parser (viele nützliche Links verwenden hier: java html-Parser ).

Der Prozess wird als 'Grabbing Website-Inhalte'. Search 'greifen Website-Inhalte java' für weitere invertigation.

jsoup unterstützt Java 1.5

https://github.com/tburch/jsoup/commit/d8ea84f46e009a7f144ee414a9fa73ea187019a3

sieht aus wie dieser Stapel war ein Fehler und wird behoben

JSoup Lösung ist groß, aber wenn man es nur etwas wirklich einfach brauchen extrahieren kann einfacher sein Regex zu verwenden oder String.indexOf

Wie andere bereits das Verfahren erwähnt heißt Schaben

Sie würden wahrscheinlich wollen im HTML, um zu sehen, wenn Sie Strings finden, die einzigartig und in der Nähe von Ihrem Text sind, dann können Sie Linie / char-Offsets verwenden, um die Daten zu erhalten.

Könnte in Java unangenehm sein, wenn es keine XML-Klassen ähnlich denen, die gefunden sind in System.XML.Linq in C #.

Sie können auch versuchen, jARVEST .

Es basiert auf einem JRuby DSL über ein reines Java-Engine zu Spider-Kratz-Transformation Web-Sites.

Beispiel: :

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);
  }

Meine Antwort wird wahrscheinlich nicht an den Verfasser dieser Frage nützlich sein (ich bin 8 Monate spät so nicht der richtige Zeitpunkt glaube ich), aber ich denke, es wird wahrscheinlich auch für viele andere Entwickler nützlich sein, die sich über diese Antwort kommen könnte.

Heute habe ich gerade freigegeben (im Namen meiner Firma) ein HTML zu POJO komplettes Framework, dass Sie mit nur einigen Anmerkungen HTML zu einer POJO Klasse abzubilden verwenden können. Die Bibliothek selbst ist recht handlich und verfügt über viele andere Dinge, die ganze Zeit sehr steckbar zu sein. Sie können hier einen Blick darauf haben: https://github.com/whimtrip/jwht-htmltopojo

Wie zu verwenden: Basics

Stellen benötigen wir folgende HTML-Seite analysieren:

<html>
    <head>
        <title>A Simple HTML Document</title>
    </head>
    <body>
        <div class="restaurant">
            <h1>A la bonne Franquette</h1>
            <p>French cuisine restaurant for gourmet of fellow french people</p>
            <div class="location">
                <p>in <span>London</span></p>
            </div>
            <p>Restaurant n*18,190. Ranked 113 out of 1,550 restaurants</p>  
            <div class="meals">
                <div class="meal">
                    <p>Veal Cutlet</p>
                    <p rating-color="green">4.5/5 stars</p>
                    <p>Chef Mr. Frenchie</p>
                </div>

                <div class="meal">
                    <p>Ratatouille</p>
                    <p rating-color="orange">3.6/5 stars</p>
                    <p>Chef Mr. Frenchie and Mme. French-Cuisine</p>
                </div>

            </div> 
        </div>    
    </body>
</html>

erstellen Lassen Sie uns die POJOs wir abbilden wollen es an:

public class Restaurant {

    @Selector( value = "div.restaurant > h1")
    private String name;

    @Selector( value = "div.restaurant > p:nth-child(2)")
    private String description;

    @Selector( value = "div.restaurant > div:nth-child(3) > p > span")    
    private String location;    

    @Selector( 
        value = "div.restaurant > p:nth-child(4)"
        format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
        indexForRegexPattern = 1,
        useDeserializer = true,
        deserializer = ReplacerDeserializer.class,
        preConvert = true,
        postConvert = false
    )
    // so that the number becomes a valid number as they are shown in this format : 18,190
    @ReplaceWith(value = ",", with = "")
    private Long id;

    @Selector( 
        value = "div.restaurant > p:nth-child(4)"
        format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
        // This time, we want the second regex group and not the first one anymore
        indexForRegexPattern = 2,
        useDeserializer = true,
        deserializer = ReplacerDeserializer.class,
        preConvert = true,
        postConvert = false
    )
    // so that the number becomes a valid number as they are shown in this format : 18,190
    @ReplaceWith(value = ",", with = "")
    private Integer rank;

    @Selector(value = ".meal")    
    private List<Meal> meals;

    // getters and setters

}

Und nun die Meal Klasse auch:

public class Meal {

    @Selector(value = "p:nth-child(1)")
    private String name;

    @Selector(
        value = "p:nth-child(2)",
        format = "^([0-9.]+)\/5 stars$",
        indexForRegexPattern = 1
    )
    private Float stars;

    @Selector(
        value = "p:nth-child(2)",
        // rating-color custom attribute can be used as well
        attr = "rating-color"
    )
    private String ratingColor;

    @Selector(
        value = "p:nth-child(3)"
    )
    private String chefs;

    // getters and setters.
}

Wir stellten einige weitere Erläuterungen zu den obigen Code auf unserer Seite Github.

Für den Moment wollen wir mal sehen, wie diese verschrotten.

private static final String MY_HTML_FILE = "my-html-file.html";

public static void main(String[] args) {


    HtmlToPojoEngine htmlToPojoEngine = HtmlToPojoEngine.create();

    HtmlAdapter<Restaurant> adapter = htmlToPojoEngine.adapter(Restaurant.class);

    // If they were several restaurants in the same page, 
    // you would need to create a parent POJO containing
    // a list of Restaurants as shown with the meals here
    Restaurant restaurant = adapter.fromHtml(getHtmlBody());

    // That's it, do some magic now!

}


private static String getHtmlBody() throws IOException {
    byte[] encoded = Files.readAllBytes(Paths.get(MY_HTML_FILE));
    return new String(encoded, Charset.forName("UTF-8"));

}

Ein weiteres kurzes Beispiel kann hier

finden

Hope Dies wird helfen, jemand da draußen!

Blick in die cURL Bibliothek. Ich habe es nie benutzt in Java, aber ich bin sicher, es muss Bindungen für sie sein. Im Grunde, was Sie tun, ist eine cURL Anfrage senden, was auch immer Seite Sie wollen ‚Scrape‘. Der Antrag wird eine Zeichenfolge mit dem Quellcode der Seite zurückzukehren. Von dort werden Sie Regex verwenden, um alle Daten, die Sie von dem Quellcode wollen zu analysieren. Das ist im Allgemeinen, wie Sie es tun werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top