Using Java, how can I extract all the links from a given web page?
royhowie
11k14 gold badges49 silver badges67 bronze badges
asked Feb 25, 2011 at 16:57
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 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
3421 gold badge2 silver badges13 bronze badges
answered Feb 25, 2011 at 17:35
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ŭ
10.5k19 gold badges92 silver badges190 bronze badges
answered Mar 6, 2011 at 22:06
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;
}
}
answered Jul 29, 2016 at 18:13
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
3411 gold badge3 silver badges14 bronze badges
answered Dec 23, 2014 at 16:04
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
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();
}
asked Jun 22, 2016 at 19:14
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
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
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”. Если вам интересно узнать о курсе подробнее, а также познакомиться с преподавателем, приглашаем на день открытых дверей онлайн.