Извлечение ссылок с веб-страницы - PullRequest
18 голосов
/ 25 февраля 2011

Используя Java, как я могу извлечь все ссылки с данной веб-страницы?

Ответы [ 6 ]

17 голосов
/ 25 февраля 2011

загрузить файл Java в виде обычного текста / html, пропустите его через Jsoup или html cleaner оба схожи и могут использоваться для анализа даже искаженного синтаксиса html 4.0, а затем вы можете использоватьпопулярные методы синтаксического анализа HTML DOM, такие как getElementsByName ("a") или в jsoup, это даже круто, вы можете просто использовать

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

и найти все ссылки, а затем получить детали с помощью

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

Взято из http://jsoup.org/cookbook/extracting-data/selector-syntax

Селекторы имеют тот же синтаксис, что и jQuery, если вы знаете цепочку функций jQuery, тогда вам, безусловно, понравится.

РЕДАКТИРОВАТЬ: Если вы хотите больше учебников, вы можетеопробуйте этот, сделанный mkyong.

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

6 голосов
/ 25 февраля 2011

Либо используйте регулярное выражение и соответствующие классы, либо используйте анализатор HTML. Какой из них вы хотите использовать, зависит от того, хотите ли вы иметь возможность обрабатывать весь веб-сайт или только несколько конкретных страниц, для которых вы знаете макет и с которыми можно проверить.

Простое регулярное выражение, которое соответствует 99% страниц, может быть таким:

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

Вы можете отредактировать его, чтобы он соответствовал большему количеству, был более совместим со стандартами и т. Д., Но в этом случае вам нужен настоящий парсер. Если вас интересуют только href = "" и текст между ними, вы также можете использовать это регулярное выражение:

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

И получить доступ к части ссылки с помощью .group(1) и текстовой части с помощью .group(2)

3 голосов
/ 07 марта 2011

Вы можете использовать библиотеку HTML Parser для достижения этой цели:

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;
}
2 голосов
/ 29 июля 2016

Этот простой пример, кажется, работает, с использованием регулярного выражения отсюда

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

и, если вам это нужно, это также работает для получения HTML-адреса URL,возвращая ноль, если это не может быть захвачено.Он также отлично работает с https URL-адресами.

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 голосов
/ 23 декабря 2014
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
            }
        }
    }
}
1 голос
/ 25 февраля 2011

Возможно, вам потребуется использовать регулярные выражения в тегах HTML-ссылок <a href=> и </a>

...