Comment « scan » d'un site Web (ou une page) pour plus d'informations, et le mettre dans mon programme?

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

  •  26-09-2019
  •  | 
  •  

Question

Eh bien, je suis à peu près à essayer de comprendre comment de tirer des informations d'une page Web, et le mettre dans mon programme (en Java).

Par exemple, si je sais la page exacte que je veux informations du, par souci de simplicité Best Buy page article, comment pourrais-je obtenir l'information appropriée dont j'ai besoin de de cette page? Comme le titre, le prix, la description?

Qu'est-ce que ce processus même appelé? Je ne sais pas été à même de commencer des recherches sur ce sujet.

Edit: D'accord, je suis en cours d'exécution d'un test pour le JSoup (celui affiché par BalusC), mais je continue à obtenir cette erreur:

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)

Je n'ai Apache Commons

Était-ce utile?

La solution

Utilisez un analyseur HTML comme Jsoup . Cela a ma préférence au-dessus de l'autre HTML puisqu'il soutien comme href="http://www.w3.org/TR/CSS2/selector.html" rel="noreferrer"> CSS sélecteurs . En outre, sa classe représentant une liste de nœuds, Elements , met en œuvre Iterable afin que vous puissiez itérer dans un < a href = « http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html » rel = « noreferrer »> amélioré pour la boucle (donc il n'y a pas besoin de tracas avec bavard Node et NodeList comme les classes dans l'analyseur moyen Java DOM).

Voici un exemple de coup d'envoi de base (il suffit de mettre le dernière Jsoup fichier JAR 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());
        }
    }

}

Comme vous l'avez deviné, ce imprime votre propre question et les noms de tous answerers.

Autres conseils

J'utiliser JTidy - il est simlar JSoup, mais je ne sais pas bien JSoup. poignées JTidy brisées HTML et renvoie un document w3c, de sorte que vous pouvez l'utiliser comme une source de XSLT pour extraire le contenu que vous êtes vraiment intéressé. Si vous ne savez pas XSLT, alors vous pourriez aussi bien aller avec JSoup, comme le document modèle est plus agréable de travailler avec de w3c.

EDIT: Un rapide coup d'oeil sur le site JSoup montre que JSoup peut en effet être le meilleur choix. Il semble soutenir sélecteurs CSS sur la boîte pour extraire des choses du document. Cela peut être beaucoup plus facile à travailler que d'entrer dans XSLT.

Vous pouvez utiliser un analyseur html (de nombreux liens utiles ici: java html parser ).

Le processus est appelé «accaparement contenu du site Web. Recherche 'contenu site grab java' pour invertigation plus loin.

supports de jsoup de 1,5

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

ressemble à cette pile était un bug, et a été corrigé

solution JSoup est grande, mais si vous avez besoin d'extraire juste quelque chose très simple, il peut être plus facile à utiliser regex ou String.indexOf

Comme d'autres l'ont déjà mentionné le processus est appelé grattage

Vous auriez probablement envie de regarder le code HTML pour voir si vous pouvez trouver des chaînes qui sont uniques et près de votre texte, vous pouvez utiliser des décalages-char ligne / pour obtenir les données.

Peut-être maladroit en Java, s'il n'y a pas de classes XML semblables à ceux trouvés dans System.XML.Linq en C #.

Vous pouvez également essayer jARVEST .

Il est basé sur une connexion DSL JRuby sur un moteur pur Java pour Spider-écorçage transformer les sites web.

Exemple :

Trouver tous les liens contenus dans une page Web (wget et xpath sont des constructions de la langue du jARVEST):

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

Dans un programme 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);
  }

Ma réponse ne sera probablement pas utile à l'auteur de cette question (je suis 8 mois de retard afin de ne pas le bon timing, je suppose) mais je pense que ce sera probablement utile pour beaucoup d'autres développeurs qui pourraient venir dans cette réponse.

Aujourd'hui, je vient de sortir (au nom de mon entreprise) un fichier HTML à POJO cadre complet que vous pouvez utiliser pour la carte HTML à une classe POJO avec simplement quelques annotations. La bibliothèque elle-même est tout à fait maniable et dispose bien d'autres choses tout en étant très connectable. Vous pouvez jeter un oeil à ce ici: https://github.com/whimtrip/jwht-htmltopojo

Comment utiliser: Principes de base

Imaginez que nous devons analyser la page HTML suivante:

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

Créons les POJO que nous voulons la carte à:

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

}

Et maintenant la classe Meal ainsi:

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

Nous avons fourni quelques explications sur plus le code ci-dessus sur notre page GitHub.

Pour le moment, nous allons voir comment cette ferraille.

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 autre exemple peut être trouvé à court

Hope this quelqu'un d'aide là-bas!

Regardez dans la bibliothèque cURL. Je ne l'ai jamais utilisé en Java, mais je suis sûr qu'il doit y avoir des liaisons pour elle. Au fond, ce que vous allez faire est d'envoyer une demande de cURL à quelle page vous voulez « scrape ». La demande retourne une chaîne avec le code source à la page. A partir de là, vous allez utiliser regex pour analyser toutes les données que vous voulez à partir du code source. C'est généralement la façon dont vous allez le faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top