Come “scan” un sito web (o una pagina) per informazioni, e portarlo nel mio programma?

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

  •  26-09-2019
  •  | 
  •  

Domanda

Bene, sono più o meno a cercare di capire come tirare le informazioni da una pagina web, e portarlo nel mio programma (in Java).

Per esempio, se so che la pagina esatta che voglio informazioni da, per semplicità una pagina voce di Best Buy, come faccio a ottenere le informazioni appropriate ho bisogno fuori di quella pagina? Come il titolo, prezzo, descrizione?

Cosa sarebbe questo processo anche essere chiamato? Non ho idea dovesse iniziare anche la ricerca di questo.

Modifica: Va bene, sto correndo un test per la JSoup (quello pubblicato da BalusC), ma continuo a ricevere questo errore:

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)

Io ho Apache Commons

È stato utile?

Soluzione

Usa un parser HTML come Jsoup . Questo ha la mia preferenza al di sopra del altro HTML parser disponibili in Java poiché jQuery come CSS selettori . Inoltre, la sua classe che rappresenta una lista di nodi, Elements , implementa Iterable in modo che si può scorrere su di esso in un < a href = "http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html" rel = "noreferrer"> migliorata per il ciclo (quindi non c'è bisogno di fastidio con verbose Node e NodeList come le classi nella media parser Java DOM).

Ecco un esempio di base kickoff (appena messo il ultimo file JAR Jsoup nel 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());
        }
    }

}

Come si può immaginare, questo stampa la propria domanda e il nome di tutti answerers.

Altri suggerimenti

Questo è indicato come screen scraping, Wikipedia ha questo articolo sul più specifica web scraping . Può essere una sfida importante perché c'è un po 'brutto, pasticcio-up, broken-se-non-per-browser HTML intelligenza là fuori, quindi buona fortuna.

I userebbe JTidy - è simlar a JSoup, ma non so bene JSoup. maniglie JTidy rotti HTML e restituisce un documento del W3C, in modo da poter utilizzare questo come una fonte di XSLT per estrarre il contenuto che si sta veramente interessato a. Se non si conosce XSLT, allora si potrebbe anche andare con JSoup, come il Documento il modello è più bello da lavorare rispetto W3C.

EDIT: Una rapida occhiata sul sito web JSoup spettacoli che JSoup può effettivamente essere la scelta migliore. Sembra di sostenere selettori CSS fuori la scatola per estrarre roba dal documento. Questo può essere molto più facile da lavorare rispetto entrare in XSLT.

È possibile utilizzare un parser HTML (molti link utili qui: java html parser ).

Il processo è chiamato 'catturare contenuto del sito'. Cerca 'contenuto del sito afferrare java' per ulteriori invertigation.

supporti jsoup Java 1.5

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

appare come quella pila era un bug, ed è stato fissato

soluzione JSoup è grande, ma se è necessario estrarre solo qualcosa di molto semplice, può essere più facile da usare regex o String.indexOf

Come altri hanno già menzionato il processo è chiamato raschiando

Si sarebbe probabilmente desidera guardare il codice HTML per vedere se è possibile trovare le stringhe che sono unici e vicino al vostro testo, quindi è possibile utilizzare la linea / char-offset per arrivare ai dati.

potrebbe essere imbarazzante in Java, se non ci sono classi XML simili a quelli trovati in System.XML.Linq in C #.

Si potrebbe anche provare jARVEST .

Si basa su un JRuby DSL nel corso di un puro Java motore Spider-raschiare-trasformare i siti web.

Esempio :

Trova tutti i link all'interno di una pagina web (wget e xpath sono costrutti del linguaggio del jARVEST):

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

All'interno di un programma Java:

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

La mia risposta non sarà probabilmente utile per lo scrittore di questa domanda (I am 8 mesi di ritardo, quindi non il giusto tempismo immagino), ma penso che probabilmente sarà utile per molti altri sviluppatori che potrebbero incontrato questa risposta.

Oggi, ho appena pubblicato (in nome della mia azienda) un HTML per POJO quadro completo che può essere utilizzato per mappare HTML per qualsiasi classe POJO con semplicemente alcune annotazioni. La libreria stessa è piuttosto comodo e dispone di molte altre cose tutte le pur essendo molto pluggable. Si può avere uno sguardo ad esso proprio qui: https://github.com/whimtrip/jwht-htmltopojo

Come usare: Nozioni di base

Immaginate abbiamo bisogno di analizzare la seguente pagina HTML:

<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>

Creiamo i POJO vogliamo mappare a:

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

}

E ora la classe Meal così:

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.
}

Abbiamo fornito alcune ulteriori spiegazioni sul codice di cui sopra sulla nostra pagina GitHub.

Per il momento, vediamo come per la demolizione questo.

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

}

Un altro breve esempio può essere trovato qui

Spero che questo vi aiuterà qualcuno là fuori!

Cercare nella libreria cURL. Non ho mai usato in Java, ma sono sicuro che ci deve essere binding per esso. In sostanza, ciò che potrete fare è inviare una richiesta cURL a qualsiasi pagina che si desidera 'raschiare'. La richiesta restituirà una stringa con il codice sorgente per la pagina. Da lì, si utilizzerà regex per analizzare qualsiasi dato che si desidera dal codice sorgente. Ecco generalmente come avete intenzione di farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top