Java как найти все ссылки

Using Java, how can I extract all the links from a given web page?

royhowie's user avatar

royhowie

11k14 gold badges49 silver badges67 bronze badges

asked Feb 25, 2011 at 16:57

Wassim AZIRAR's user avatar

Wassim AZIRARWassim AZIRAR

10.8k38 gold badges120 silver badges172 bronze badges

1

download java file as plain text/html pass it through Jsoup or html cleaner both are similar and can be used to parse even malformed html 4.0 syntax and then you can use the popular HTML DOM parsing methods like getElementsByName(“a”) or in jsoup its even cool you can simply use

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

and find all links and then get the detials using

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

Taken from http://jsoup.org/cookbook/extracting-data/selector-syntax

The selectors have same syntax as jQuery if you know jQuery function chaining then you will certainly love it.

EDIT: In case you want more tutorials, you can try out this one made by mkyong.

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

answered Feb 25, 2011 at 17:36

samarjit samanta's user avatar

samarjit samantasamarjit samanta

1,2852 gold badges16 silver badges29 bronze badges

0

Either use a Regular Expression and the appropriate classes or use a HTML parser. Which one you want to use depends on whether you want to be able to handle the whole web or just a few specific pages of which you know the layout and which you can test against.

A simple regex which would match 99% of pages could be this:

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

You can edit it to match more, be more standard compliant etc. but you would want a real parser in that case.
If you are only interested in the href=”” and text in between you can also use this regex:

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

And access the link part with .group(1) and the text part with .group(2)

Henry's user avatar

Henry

3421 gold badge2 silver badges13 bronze badges

answered Feb 25, 2011 at 17:35

dtech's user avatar

2

You can use the HTML Parser library to achieve this:

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

Rudziankoŭ's user avatar

Rudziankoŭ

10.5k19 gold badges92 silver badges190 bronze badges

answered Mar 6, 2011 at 22:06

shams's user avatar

shamsshams

3,46024 silver badges24 bronze badges

2

This simple example seems to work, using a regex from here

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

and if you need it, this seems to work to get the HTML of an url as well, returning null if it can’t be grabbed. It works fine with https urls as well.

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

Community's user avatar

answered Jul 29, 2016 at 18:13

Brad Parks's user avatar

Brad ParksBrad Parks

65.5k63 gold badges255 silver badges331 bronze badges

3

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

Eagle's user avatar

Eagle

3411 gold badge3 silver badges14 bronze badges

answered Dec 23, 2014 at 16:04

jfabrizio's user avatar

jfabriziojfabrizio

7607 silver badges15 bronze badges

1

You would probably need to use regular expressions on the HTML link tags <a href=> and </a>

answered Feb 25, 2011 at 17:01

MattLBeck's user avatar

MattLBeckMattLBeck

5,6517 gold badges40 silver badges56 bronze badges

1

I wrote a program to get all the links from a webpage and then get all the links from that sub page.

For example: I have page www.example.com and found five other links: example.com/home, example.com/contact, etc. I should go to these links and check again for links on that webpage.

How should I implement this?

Also, I need a list of already visited pages and blocked pages (Link to Facebook, for example, because then I think it will be in the infinite loop).

Here is my code so far (Which only gives me the links from one webpage and not its subpages):

 try {
        Document doc = Jsoup.connect("https://www.example.com/").get();
        Elements elements = doc.select("a");
        for(Element element : elements){
            System.out.println(element.absUrl("href"));
            list.add(element.absUrl("href"));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

MasterBlaster's user avatar

asked Jun 22, 2016 at 19:14

asd11_81's user avatar

2

You can use recursion. Put your code in a method, for example

void getLinks(String url, Set<String> urls) {

    if (urls.contains(url)) {
        return;
    }
    urls.add(url);

    try {
        Document doc = Jsoup.connect(url).get();
        Elements elements = doc.select("a");
        for(Element element : elements){
            System.out.println(element.absUrl("href"));
            getLinks(element.absUrl("href"), urls);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Then you can start the execution like this:

Set<String> links = new HashSet<>();
getLinks("https://www.example.com/", links);

answered Jun 22, 2016 at 20:40

BCartolo's user avatar

BCartoloBCartolo

7204 silver badges21 bronze badges

3

After adding all the links to your list of links

try {
    Document doc = Jsoup.connect("https://www.example.com/").get();
    Elements elements = doc.select("a");
    for(Element element : elements){
        System.out.println(element.absUrl("href"));
        list.add(element.absUrl("href")); //<-------HERE*****
    }
} catch (IOException e) {
    e.printStackTrace();
}

You can then simply connect to each one of those in the same way that you connected to the first one, using

for(int i = 0; i < list.size(); i++){
    doc = Jsoup.connect(list.get(i)).get();
    //do whatever you want
}

If you don’t want a particular link, I’d recommend putting the undesired links in a hashmap, and checking against them before adding them to your list(s) of links to other pages.

answered Jun 22, 2016 at 20:37

Mr. DROP TABLE's user avatar

1

Синтаксический анализатор HTML jsoup пример, показывающий, как анализировать и получать все HTML-гиперссылки с веб-страницы:

package com.mkyong;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class JsoupFindLinkSample {

    public static void main(String[] args) throws IOException {

        for (String link : findLinks("https://google.com")) {
            System.out.println(link);
        }

    }

    private static Set findLinks(String url) throws IOException {

        Set links = new HashSet<>();

        Document doc = Jsoup.connect(url)
                .data("query", "Java")
                .userAgent("Mozilla")
                .cookie("auth", "token")
                .timeout(3000)
                .get();

        Elements elements = doc.select("a[href]");
        for (Element element : elements) {
            links.add(element.attr("href"));
        }

        return links;

    }

}

Выход

https://play.google.com/?hl=en&tab=w8
https://www.google.com/calendar?tab=wc
/intl/en/about.html
https://photos.google.com/?tab=wq&pageId=none
https://drive.google.com/?tab=wo

//...

Рекомендации

  • синтаксический анализатор HTML jsoup примеры hello world
  • спуп: Синтаксический анализатор Java HTML

Оригинал: “https://mkyong.com/java/java-how-to-get-all-links-from-a-web-page/”


  • Метки


    page, web

Вопрос:

как мы можем узнать отсутствие гиперссылок на странице.
и как узнать, что все они?
Мне нужно развить материал в java плана не в какой-либо работе кадра, а это значит, используя метод JAVA.NET. *;, любую область? Как я могу это сделать?
можете ли вы, ребята, дать мне правильный пример?

Мне нужно получить все ссылки на странице, и мне нужно сохранить их в базе данных, все ссылки с именем домена

Лучший ответ:

Попробуйте использовать jsoup library.

Загрузите jar проекта и скомпилируйте этот фрагмент кода:

    Document doc = Jsoup.parse(new URL("http://www.bits4beats.it/"), 2000);

    Elements resultLinks = doc.select("a");
    System.out.println("number of links: " + resultLinks.size());
    for (Element link : resultLinks) {
        System.out.println();
        String href = link.attr("href");
        System.out.println("Title: " + link.text());
        System.out.println("Url: " + href);
    }

Код печатает числа гипертекстовых элементов на странице html и информацию о них.

Ответ №1

Вы можете использовать пакеты javax.swing.text.html и javax.swing.text.html.parser для достижения этого:

import java.io.*;
import java.net.URL;
import java.util.Enumeration;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;

public class Test {
public static void main(String[] args) throws Exception  {
Reader r = null;

try   {
URL u = new URL(args[0]);
InputStream in = u.openStream();
r = new InputStreamReader(in);

ParserDelegator hp = new ParserDelegator();
hp.parse(r, new HTMLEditorKit.ParserCallback() {
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// System.out.println(t);
if(t == HTML.Tag.A)  {
Enumeration attrNames = a.getAttributeNames();
StringBuilder b = new StringBuilder();
while(attrNames.hasMoreElements())    {
Object key = attrNames.nextElement();
if("href".equals(key.toString())) {
System.out.println(a.getAttribute(key));
}
}
}
}
}, true);
}finally {
if(r != null)  {
r.close();
}
}
}
}

Скомпилируйте и назовите его следующим образом:

java Test http://www.oracle.com/technetwork/java/index.html

Ответ №2

Наилучшим вариантом является использование некоторой библиотеки парсеров html, но если вы не хотите использовать какую-либо такую ​​стороннюю библиотеку, вы можете попытаться сделать это, сопоставив ее с регулярным выражением, используя классы Java и Pattern Matcher из regex.

Edit
Пример:

String regex="\b(?<=(href="))[^"]*?(?=")";
Pattern pattern = Pattern.compile(regex);

Matcher m = pattern.matcher(str_YourHtmlHere);
while(m.find()) {
System.out.println("FOUND: " + m.group());
}

В приведенном выше примере это простое базовое регулярное выражение, которое найдет все ссылки, указанные атрибутом href. Возможно, вам придется усилить регулярное выражение для правильной обработки всех сценариев, таких как href с url в одинарной цитате и т.д.

Ответ №3

Ответ №4

    Pattern p = Pattern.compile("(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)");

Matcher m = p.matcher(br.toString());


while (m.find() == true) {

resp.getWriter().print("<a href="+m.group(0).toString()+">"+m.group(0).toString()+"</a><br/>");
}

Время на прочтение
3 мин

Количество просмотров 3.5K

Когда вам нужно проверить все ссылки в вашем проекте, вы можете сделать это с помощью Postman или любого другого инструмента тестирования API, но есть более простой способ. Когда вы используете инструменты тестирования API, вам нужно написать все соединения ссылок один за другим, а когда ссылки меняются, вам нужно снова редактировать все тесты один за другим.

Теперь с помощью этого java-кода вы можете проверить все ссылки. Эти ссылки могут быть ссылками pdf, изображения, видео или фотографии.

Шаг 1: В HTML мы связываем ссылки с помощью этого кода: <a href="Adress"></a> это означает, что мы должны собрать все ссылки на веб-странице на основе <a>. Для этого мы используем этот код:

List<WebElement> allLinks = driver.findElements(By.tagName(LINKS_TAG));

LINKS_TAG – это “a”. В конце страницы я добавлю весь код.

Шаг 2: Определение и проверка URL-адреса

String urlLink = link.getAttribute(LINKS_ATTRIBUTE);

LINKS_ATTRIBUTE – это “href”

Шаг 3: Отправка HTTP-запроса и считывание кодов HTTP-ответов

Мы создаем HttpConnection с параметром URL. Я добавил также Connection Timeout.

URL url = new URL(urlLink);
HttpURLConnection httpURLConnect=(HttpURLConnection)url.openConnection();
httpURLConnect.setConnectTimeout(5000);
httpURLConnect.connect();
  • Информационные коды ответов: 100-199

  • Коды успешного ответа: 200-299

  • Редирект коды: 300-399

  • Коды ошибок клиента: 400-499

  • Коды ошибок сервера: 500-599

В принципе, мы можем сказать, что если код ответа больше или равен 400, то в этом случае соединение прервано.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;


public class FindAllBrokenLinks {
    public final String DRIVER_PATH = "Drivers/chromedriver";
    public final String DRIVER_TYPE = "webdriver.chrome.driver";
    public WebDriver driver;
    public final String BASE_URL = "https://www.bbc.com/";
    public final String LINKS_ATTRIBUTE = "href";
    public final String LINKS_TAG = "a";

    @BeforeTest
    public void beforeTest(){
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--disable-notifications","--ignore-certificate-errors","--disable-extensions");
        System.setProperty(DRIVER_TYPE,DRIVER_PATH);
        driver = new ChromeDriver(options);
        driver.manage().window().maximize();
        driver.get(BASE_URL);
    }

    @Test
    public void FindAllBrokenLinks() throws Exception{
        List<WebElement> allLinks = driver.findElements(By.tagName(LINKS_TAG));
        for(WebElement link:allLinks){
            try {
                String urlLink = link.getAttribute(LINKS_ATTRIBUTE);
                URL url = new URL(urlLink);
                HttpURLConnection httpURLConnect=(HttpURLConnection)url.openConnection();
                httpURLConnect.setConnectTimeout(5000);
                httpURLConnect.connect();
                if(httpURLConnect.getResponseCode()>=400)
                {
                    System.out.println(urlLink+" - "+httpURLConnect.getResponseMessage()+"is a broken link");
                }
                else{
                    System.out.println(urlLink+" - "+httpURLConnect.getResponseMessage());
                }
            }catch (Exception e) {
            }
        }

    }

    @AfterClass
    public void CloseDriver(){
        driver.close();

    }
}

Я использовал URL веб-страницы BBC в качестве базового URL, но запуск этого кода занял 1 минуту и 49 секунд. 🙂 Возможно, вам стоит выбрать другой сайт.

Вот некоторые результаты тестов:

https://www.bbc.com/sport — OK

https://www.bbc.com/reel — OK

https://www.bbc.com/worklife — OK

https://www.bbc.com/travel — Временно приостановил работу

https://www.bbc.com/future — OK

https://www.bbc.com/culture — OK

https://www.bbc.com/culture/music — OK

http://www.bbc.co.uk/worldserviceradio/ — Не доступен

http://www.bbc.co.uk/programmes/p00wf2qw — Не доступен

https://www.bbc.com/news/world-europe-57039362 — OK


Перевод подготовлен в рамках набора учащихся на курс “Java QA Automation Engineer”. Если вам интересно узнать о курсе подробнее, а также познакомиться с преподавателем, приглашаем на день открытых дверей онлайн.

Добавить комментарий