web-dev-qa-db-fra.com

Extraire les liens d'une page Web

En utilisant Java, comment puis-je extraire tous les liens d'une page Web donnée?

19
Wassim AZIRAR

télécharger Java fichier en texte brut/html le faire passer Jsoup ou nettoyeur html les deux sont similaires et peuvent être utilisés pour analyser même la syntaxe html 4.0 malformée, puis vous pouvez utiliser les méthodes d'analyse HTML DOM populaires comme getElementsByName ("a") ou dans jsoup c'est même cool, vous pouvez simplement utiliser

File input = new File("/tmp/input.html");
 Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

Elements links = doc.select("a[href]"); // a with href
Elements pngs = doc.select("img[src$=.png]");
// img with src ending .png

Element masthead = doc.select("div.masthead").first();

et trouver tous les liens, puis obtenir les détails en utilisant

String linkhref=links.attr("href");

Tiré de http://jsoup.org/cookbook/extracting-data/selector-syntax

Les sélecteurs ont la même syntaxe que jQuery si vous connaissez le chaînage de fonctions jQuery, vous l'aimerez certainement.

EDIT: Si vous souhaitez plus de tutoriels, vous pouvez essayer celui-ci fait par mkyong.

http://www.mkyong.com/Java/jsoup-html-parser-hello-world-examples/

17
samarjit samanta

Utilisez une expression régulière et les classes appropriées ou utilisez un analyseur HTML. Lequel vous souhaitez utiliser dépend de si vous voulez être capable de gérer l'ensemble du Web ou seulement quelques pages spécifiques dont vous connaissez la mise en page et que vous pouvez tester.

Une expression régulière simple qui correspondrait à 99% des pages pourrait être la suivante:

// The HTML page as a String
String HTMLPage;
Pattern linkPattern = Pattern.compile("(<a[^>]+>.+?<\/a>)",  Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
Matcher pageMatcher = linkPattern.matcher(HTMLPage);
ArrayList<String> links = new ArrayList<String>();
while(pageMatcher.find()){
    links.add(pageMatcher.group());
}
// links ArrayList now contains all links in the page as a HTML tag
// i.e. <a att1="val1" ...>Text inside tag</a>

Vous pouvez le modifier pour qu'il corresponde davantage, être plus conforme aux normes, etc., mais vous voudriez un véritable analyseur dans ce cas. Si vous n'êtes intéressé que par le href = "" et le texte entre les deux, vous pouvez également utiliser cette expression régulière:

Pattern linkPattern = Pattern.compile("<a[^>]+href=[\"']?([\"'>]+)[\"']?[^>]*>(.+?)<\/a>",  Pattern.CASE_INSENSITIVE|Pattern.DOTALL);

Et accédez à la partie lien avec .group(1) et à la partie texte avec .group(2)

6
dtech

Vous pouvez utiliser la bibliothèque HTML Parser pour y parvenir:

public static List<String> getLinksOnPage(final String url) {
    final Parser htmlParser = new Parser(url);
    final List<String> result = new LinkedList<String>();

    try {
        final NodeList tagNodeList = htmlParser.extractAllNodesThatMatch(new NodeClassFilter(LinkTag.class));
        for (int j = 0; j < tagNodeList.size(); j++) {
            final LinkTag loopLink = (LinkTag) tagNodeList.elementAt(j);
            final String loopLinkStr = loopLink.getLink();
            result.add(loopLinkStr);
        }
    } catch (ParserException e) {
        e.printStackTrace(); // TODO handle error
    }

    return result;
}
3
shams

Cet exemple simple semble fonctionner, en utilisant une expression régulière d'ici

import Java.util.regex.Matcher;
import Java.util.regex.Pattern;

public ArrayList<String> extractUrlsFromString(String content)
{
    ArrayList<String> result = new ArrayList<String>();

    String regex = "(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(content);
    while (m.find())
    {
        result.add(m.group());
    }

    return result;
}

et si vous en avez besoin, cela semble également fonctionner pour obtenir le code HTML d'une URL, renvoyant null si elle ne peut pas être récupérée. Cela fonctionne aussi bien avec les URL https.

import org.Apache.commons.io.IOUtils;

public String getUrlContentsAsString(String urlAsString)
{
    try
    {
        URL url = new URL(urlAsString);
        String result = IOUtils.toString(url);
        return result;
    }
    catch (Exception e)
    {
        return null;
    }
}
2
Brad Parks
import Java.io.*;
import Java.net.*;

public class NameOfProgram {
    public static void main(String[] args) {
        URL url;
        InputStream is = null;
        BufferedReader br;
        String line;

        try {
            url = new URL("http://www.stackoverflow.com");
            is = url.openStream();  // throws an IOException
            br = new BufferedReader(new InputStreamReader(is));

            while ((line = br.readLine()) != null) {
                if(line.contains("href="))
                    System.out.println(line.trim());
            }
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException ioe) {
                //exception
            }
        }
    }
}
2
jfabrizio

Vous auriez probablement besoin d'utiliser des expressions régulières sur les balises de lien HTML <a href=> et </a>

1
MattLBeck