Парсинг html страниц с выводом информации через javascript с использованием selenium

JSoup parse local HTML file

In the second example, we are going to parse a local HTML file.
We use the overloaded method that takes
a object as its first parameter.

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>My title</title>
        <meta charset="utf-8">
    </head>
    <body>
        <div id="mydiv">Contents of a div element</div>
    </body>
</html>

For the example, we use the above HTML file.

com/zetcode/JSoupFromFileEx.java

package com.zetcode;

import java.io.File;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class JSoupFromFileEx {
    
    public static void main(String[] args) throws IOException {
        
        String fileName = "src/main/resources/index.html";
        
        Document doc = Jsoup.parse(new File(fileName), "utf-8"); 
        Element divTag = doc.getElementById("mydiv"); 
        
        System.out.println(divTag.text());
    }
}

The example parses the file, which is located
in the directory.

Document doc = Jsoup.parse(new File(fileName), "utf-8"); 

We parse the HTML file with the method.

Element divTag = doc.getElementById("mydiv"); 

With the document’s method, we get
the element
by its ID.

System.out.println(divTag.text());

The text of the tag is retrieved with the element’s method.

JSoup parse links

The next example parses links from a HTML page.

com/zetcode/JSoupLinksEx.java

package com.zetcode;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class JSoupLinksEx {

    public static void main(String[] args) throws IOException {
        
        String url = "http://jsoup.org";

        Document document = Jsoup.connect(url).get();
        Elements links = document.select("a");
        
        for (Element link : links) {
            
            System.out.println("link : " + link.attr("href"));
            System.out.println("text : " + link.text());
        }
    }
}

In the example, we connect to a web page and parse all its link
elements.

Elements links = document.select("a");

To get a list of links, we use the document’s
method.

Jsoup at a Glance

Jsoup loads the page HTML and builds the corresponding DOM tree. This tree works the same way as the DOM in a browser, offering methods similar to jQuery and vanilla JavaScript to select, traverse, manipulate text/HTML/attributes and add/remove elements.

If you’re comfortable with client-side selectors and DOM traversing/manipulation, you’ll find jsoup very familiar. Check how easy it is to print the paragraphs of a page:

Bear in mind that jsoup interprets HTML only — it does not interpret JavaScript. Therefore changes to the DOM that would normally take place after page loads in a JavaScript-enabled browser will not be seen in jsoup.

BeautifulSoup

BeautifulSoup — фреймворк, также использующий популярный язык программирования Python, позволяет парсить данные из HTML и XML документов. Фреймворк предлагает подробную документацию, для открытия ссылок и сохранения результатов потребуется подключить сторонние библиотеки. Он более прост функционально по сравнению со Scrapy, BeautifulSoup стоит выбрать, если задачи парсинга не требуют распределения данных, не требуют реализации сложной логики и не нужно применять прокси сервера. Но, в противовес меньшему функционалу BeautifulSoup более прост в освоении, библиотека подойдет начинающим программистам, множество мануалов помогут быстро разобраться в продукте.

Scrapy

Scrapy — фреймворк для парсинга с открытым исходным кодом. Scrapy использует язык программирования Python и является одним из самых популярных фрейморков для парсинга. Одно из главных достоинств Scrapy — возможность асинхронной обработки запросов. Это позволяет не ждать, пока запрос будет завершен, парсер может отправлять параллельные запросы или выполнять другую логику в это время. Если в процессе вызова произойдет ошибка, парсер не прекратит свою работу, параллельные процессы продолжат выполняться.

Такой подход позволяет работать очень быстро и получать высокую отказоустойчивость запрсов. Scrapy также предлагает управление и другими параметрами парсинга, вы сможете задавать задержку между каждым запросом или группой запросов, ограничить количество одновременных запросов для каждого домена или IP адреса или даже использовать автоматический расчет нужной задержки между запросами.

Парсер на java: пример-получим данные из интернет-магазина

Сначала посмотрим, что происходит при поиске товара в магазине. Для этого откройте «Инструменты разработчика» в Chrome и перейдите на вкладку «Network»:

URL поиска:

https://newyork.craigslist.org/search/moa?is_paid=all&search_distance_type=mi&query=iphone+6s

Также можно использовать

https://newyork.craigslist.org/search/sss?sort=rel&query=iphone+6s

Теперь откройте среду разработки. Пришло время писать код. Для выполнения запроса в HtmlUnit нужен WebClient. Сначала нужно отключить JavaScript, так как в нашем примере он не нужен, и без него страница будет загружаться быстрее:

String searchQuery = "Iphone 6s" ;
WebClient client = new WebClient();
client.getOptions().setCssEnabled(false);
client.getOptions().setJavaScriptEnabled(false);
try {
String searchUrl = "https://newyork.craigslist.org/search/sss?sort=rel&query=" + URLEncoder.encode(searchQuery, "UTF-8");
HtmlPage page = client.getPage(searchUrl);
}catch(Exception e){
e.printStackTrace();
}
}

В объекте HtmlPage будет HTML-код, доступ к которому можно получить с помощью метода asXml(). Вытянем с сайта названия, изображения и цены. Для этого нужно внимательно просмотреть структуру DOM:

Для парсинга страниц сайта есть несколько способов выбрать тег HTML, используя HtmlUnit:

  • getHtmlElementById(String id);
  • getFirstByXPath(String Xpath)-getByXPath(String XPath), который возвращает список.

Поскольку мы не можем использовать ID, чтобы выбрать теги, нужно составить выражение Xpath.

XPath — это язык запросов для выбора элементов XML (в нашем случае HTML).

Сначала нужно выбрать все теги <p> с классом `result-info. Затем выполнить итерацию в списке, и для каждого предмета выбрать название, цену и URL, а также вывести на экран.

List<HtmlElement> items = (List<HtmlElement>) page.getByXPath("//p" ;
if(items.isEmpty()){
System.out.println("No items found !");
}else{
for(HtmlElement item : items){
HtmlAnchor itemAnchor =  ((HtmlAnchor) htmlItem.getFirstByXPath(".//a"));
String itemName = itemAnchor.asText();
String itemUrl = itemAnchor.getHrefAttribute() ;
HtmlElement spanPrice =((HtmlElement) htmlItem.getFirstByXPath(".//span")) ;
// Возможно, что для товара не установлена цена
String itemPrice = spanPrice == null ? "no price" : spanPrice.asText() ;
System.out.println( String.format("Name : %s Url : %s Price : %s", itemName, itemPrice, itemUrl));
}
}

Item.java

public class Item {
private String title ;
private BigDecimal price ;
private String url ;
// геттеры и сеттеры
}

Затем добавим это в файл pom.xml:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>

Теперь нужно создать элемент, задать атрибуты, конвертировать в строку или файл JSON и немного адаптировать предыдущий код парсинга данных с сайта:

for(HtmlElement htmlItem : items){
HtmlAnchor itemAnchor = ((HtmlAnchor) htmlItem.getFirstByXPath(".//span/span/a"));
HtmlElement spanPrice = ((HtmlElement) htmlItem.getFirstByXPath(".//span/span/span")) ;
// Возможно, для товара не установлена цена, в этом случае мы обозначаем ее как 0.0
String itemPrice = spanPrice == null ? "0.0" : spanPrice.asText() ;
Item item = new Item();
item.setTitle(itemAnchor.asText());
item.setUrl( baseUrl +
itemAnchor.getHrefAttribute());
item.setPrice(new BigDecimal(itemPrice.replace("$", "")));
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(item) ;
System.out.println(jsonString);
}

JSoup parse HTML string

In the first example, we are going to parse a HTML string.

com/zetcode/JSoupFromStringEx.java

package com.zetcode;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JSoupFromStringEx {

    public static void main(String[] args) {
        
        String htmlString = "<html><head><title>My title</title></head>"
                + "<body>Body content</body></html>";

        Document doc = Jsoup.parse(htmlString);
        String title = doc.title();
        String body = doc.body().text();
        
        System.out.printf("Title: %s%n", title);
        System.out.printf("Body: %s", body);
    }
}

The example parses a HTML string and outputs its title and body content.

String htmlString = "<html><head><title>My title</title></head>"
        + "<body>Body content</body></html>";

This string contains simple HTML data.

Document doc = Jsoup.parse(htmlString);

With the Jsoup’s method, we parse the HTML string. The method
returns a HTML document.

String title = doc.title();

The document’s method gets the string contents of the document’s
title element.

String body = doc.body().text();

The document’s method returns the body element; its
method gets the text of the element.

Extracting

We now know how to reach specific elements, so it’s time to get their content — namely their attributes, HTML, or child text.

Take a look at this example that selects the first article from the blog and gets its date, its first section text, and finally, its inner and outer HTML:

Here are some tips to bear in mind when choosing and using selectors:

  • Rely on “View Source” feature of your browser and not only on the page DOM as it might have changed (selecting at the browser console might yield different results than jsoup)
  • Know your selectors as there are a lot of them and it’s always good to have at least seen them before; mastering selectors takes time
  • Use a playground for selectors to experiment with them (paste a sample HTML there)
  • Be less dependent on page changes: aim for the smallest and least compromising selectors (e.g. prefer id. based)

java.util.Scanner

Класс java.util.Scanner предназначен для разбиения форматированного ввода на токены и конвертирования токенов в соответствующий тип данных.

По умолчанию сканер использует пробельные символы (пробелы, табуляторы, разделители линий) для разделения токенов. Рассмотрите следующий код:

Java

import java.io.*;
import java.util.Scanner;

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

Scanner s = null;

try {
s = new Scanner(new BufferedReader(new FileReader(«xanadu.txt»)));

while (s.hasNext()) {
System.out.println(s.next());
}
} finally {
if (s != null) {
s.close();
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

importjava.io.*;

importjava.util.Scanner;

publicclassScanXan{

publicstaticvoidmain(Stringargs)throwsIOException{

Scanners=null;

try{

s=newScanner(newBufferedReader(newFileReader(«xanadu.txt»)));

while(s.hasNext()){

System.out.println(s.next());

}

}finally{

if(s!=null){

s.close();

}

}

}

}

Если файл «xanadu.txt» содержит следующий текст:

In Xanadu did Kubla Khan
A stately pleasure-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.

1
2
3
4
5

In Xanadu did Kubla Khan
A stately pleasure-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.

То результатом работы программы будет вывод:

In
Xanadu
did
Kubla
Khan
A
stately
pleasure-dome

1
2
3
4
5
6
7
8
9

In
Xanadu
did
Kubla
Khan
A
stately
pleasure-dome

Чтобы использовать другой разделитель токенов используйте метод
useDelimiter, в который передаётся регулярное выражение. Например, предположим, что мы хотим использовать в качестве разделителя запятую, после которой может идти, а может не идти пробел:

Java

s.useDelimiter(«,\\s*»);

1 s.useDelimiter(«,\\s*»);

Класс
java.util.Scanner  поддерживает все примитивные типы Java,
java.math.BigInteger  и
java.math.BigDecimal.
Scanner  использует экземпляр
java.util.Locale  для преобразования строк в эти типы данных. Пример:

ScanSum.java

Java

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.Locale;

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

Scanner s = null;
double sum = 0;

try {
s = new Scanner(new BufferedReader(new FileReader(«usnumbers.txt»)));
s.useLocale(Locale.US);

while (s.hasNext()) {
if (s.hasNextDouble()) {
sum += s.nextDouble();
} else {
s.next();
}
}
} finally {
s.close();
}

System.out.println(sum);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

importjava.io.FileReader;

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.util.Scanner;

importjava.util.Locale;

publicclassScanSum{

publicstaticvoidmain(Stringargs)throwsIOException{

Scanners=null;

doublesum=;

try{

s=newScanner(newBufferedReader(newFileReader(«usnumbers.txt»)));

s.useLocale(Locale.US);

while(s.hasNext()){

if(s.hasNextDouble()){

sum+=s.nextDouble();

}else{

s.next();

}

}

}finally{

s.close();

}

System.out.println(sum);

}

}

Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 консоль».
Предыдущая статья — «Java 8 дата и время».

Easy Web Extract

Easy Web Extract позволяет собирать данные с простых html сайтов и сайтов с динамически подгружаемым содержимым. Для использования программы не нужны знания программирования, работа ведется через мастер, который пошагово поможет организовать настройку шаблона для парсинга. Для того, чтобы быстро освоить программа предлагает базу знаний и видео уроки.

Особенность — вы можете задать автоматический поиск нужных вам товаров на стадии настройки и собирать только нужные данные. Другая особенность Easy Web Extract — возможность многопоточного сбора, это позволит экономить время выполнения парсинга, но будте аккуратны при многопоточном сканировании, целевой сайт может блокировать ваш ip из-за подозрительной активности.

В Easy Web Extract есть возможность парсинга динамически загружаемых данных, при тестировании программа справилась не со всеми сайтами, проверьте эту возможность на нужном вам сайте.

Filtering

Now that we have the HTML converted into a Document, it’s time to navigate it and find what we are looking for. This is where the resemblance with jQuery/JavaScript is more evident, as its selectors and traversing methods are similar.

5.1. Selecting

The Document select method receives a String representing the selector, using the same selector syntax as in a CSS or JavaScript, and retrieves the matching list of Elements. This list can be empty but not null.

Let’s take a look at some selections using the select method:

You can also use more explicit methods inspired by the browser DOM instead of the generic select:

Since Element is a superclass of Document, you can learn more about working with the selection methods in the Document and Element Javadocs.

5.2. Traversing

Traversing means navigating across the DOM tree. Jsoup provides methods that operate on the Document, on a set of Elements, or on a specific Element, allowing you to navigate to a node’s parents, siblings, or children.

Also, you can jump to the first, the last, and the nth (using a 0-based index) Element in a set of Elements:

You can also iterate through selections. In fact, anything of type Elements can be iterated:

You can make a selection restricted to a previous selection (sub-selection):

Helium scraper

Helium scraper — программа для парсинга данных с сайтов. Принцип работы с программой похож на работу с рассмотренной выше программой, с отличием — вместо визуального представления действий программа показывает код. Интерфейс у программы не самый дружелюбный для неподготовленного пользователя, но программа имеет базу знаний и видео-уроки, которые помогут освоить принципы работы.

Функциональность программы имеет ряд особенностей по отношению к рассмотренным выше

Одна из ключевых — это возможность собирать большие базы данных, до 140 Терабайт, если ваша задача подразумевает сбор большого объема информации, то стоит обратить внимание на Helium scraper. Так же программа может работать через API, вы можете интегрировать запросы к целевым сайтам в свой проект

java.text.SimpleDateFormat

Класс java.text.SimpleDateFormat наследуется от
java.text.DateFormat  и позволяет указать пользовательский шаблон форматирования.

Конструкторы:

Java

public SimpleDateFormat(String pattern)

1 publicSimpleDateFormat(Stringpattern)

Java

public SimpleDateFormat(String pattern,
Locale locale)

1
2

publicSimpleDateFormat(Stringpattern,

Locale locale)

Java

public SimpleDateFormat(String pattern,
DateFormatSymbols formatSymbols)

1
2

publicSimpleDateFormat(Stringpattern,

DateFormatSymbols formatSymbols)

Конструктор с DateFormatSymbols позволяет создать форматировщик, используя особые правила.

Шаблон
pattern  может содержать следующие специальные символы:

Буква Компонент даты и времени Представление Примеры
Эра
Год ;
Год ;
Месяц в году (зависит от контекста) ; ;
Месяц в году (самостоятельная форма) ; ;
Неделя в годе
Неделя в месяце
День в году
День в месяце
День недели в месяце
Название дня недели ;
Номер дня недели (1 = Понедельник, …, 7 = Воскресенье)
Am/pm
Час в дне (0-23)
Час в дне (1-24)
Час в дне am/pm (0-11)
Час в дне am/pm (1-12)
Минуты
Секунды
Миллисекунды
Часовой пояс ; ;
Часовой пояс
Часовой пояс ; ;

Описание столбца «представление»:

  • Text: Если в шаблоне 4 буквы или более, то используется полная форма, в противном случае используется сокращённая форма. При парсинге принимаются обе формы, независимо от количества букв в шаблоне.
  • Number: Количество букв в шаблоне — это минимальное количество цифр, более короткие числа добиваются нулями. При парсинге количество букв игнорируется, если только оно не требуется для разделения соседних полей.
  • Year: Если
    Calendar  форматировщика является григорианским календарём, то применяются следующие правила. При форматировании если количество букв равно двум, то год усекается до двух цифр, в противном случае интерпретируется как число. При парсинге если количество букв больше двух, то год интерпретируется буквально, независимо от количества цифр. Поэтому использование шаблона
    «MM/dd/yyyy»  и строки
    «01/11/12»  получается 11 января 12 года нашей эры. При парсинге с сокращённой формой года (
    «y»  или
    «yy» )
    SimpleDateFormat  интерпретирует сокращённый год относительно какого-либо века. Он выравнивает даты так, чтобы они были в диапазоне от 80 лет до даты создания
    SimpleDateFormat  и до 20 лет после даты создания
    SimpleDateFormat. Во время парсинга только строки, состоящие строго из двух цифр интерпретируются в текущий век. Любые другие числовые строки, состоящие из одной цифры или трёх и более, интерпретируются как полный год.
  • Month: Если количество букв в шаблоне равно 3 или более, то месяц интерпретируется как текст, в противном случае интерпретируется как число. Буква
    M  создаёт имена месяцев, зависимые от контекста. Если в конструктор был передан
    DateFormatSymbols  или был использован метод
    setDateFormatSymbols, то имена месяцев берутся из
    DateFormatSymbols. Буква
    L  создаёт самостоятельную форму имён месяцев.
  • /a>General time zone: Часовые пояса интерпретируются по текстовым именам. При использовании смещения часовой пояс указывается в виде GMT +01:30 или GMT-12:33.
  • RFC 822 time zone: Используются четыре цифры: -0800 или +1200.
  • ISO 8601 time zone: Используются две цифры, четыре цифры, или с разделением часов и минут двоеточием: -08; -0800; -08:00.

JSoup get information

Meta information of a HTML document provides structured metadata about a Web
page, such as its description and keywords.

com/zetcode/JSoupMetaInfoEx.java

package com.zetcode;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JSoupMetaInfoEx {

    public static void main(String[] args) throws IOException {
        
        String url = "http://www.jsoup.org";
        
        Document document = Jsoup.connect(url).get();

        String description = document.select("meta").first().attr("content");
        System.out.println("Description : " + description);

        String keywords = document.select("meta").first().attr("content");
        System.out.println("Keywords : " + keywords);
    }
}

The code example retrieves meta information about a specified web page.

String keywords = document.select("meta").first().attr("content");

The document’s method finds elements that match the
given query. The method returns the first matched element.
With the method, we get the value of the
attribute.

Overview

Jsoup is an open source Java library used mainly for extracting data from HTML. It also allows you to manipulate and output HTML. It has a steady development line, great documentation, and a fluent and flexible API. Jsoup can also be used to parse and build XML.

In this tutorial, we’ll use the Spring Blog to illustrate a scraping exercise that demonstrates several features of jsoup:

  • Loading: fetching and parsing the HTML into a Document
  • Filtering: selecting the desired data into Elements and traversing it
  • Extracting: obtaining attributes, text, and HTML of nodes
  • Modifying: adding/editing/removing nodes and editing their attributes

HTML Parsing in Java using JSoup

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Login Page</title>
    </head>
    <body>
        <div id="login" class="simple" >
            <form action="login.do">
                Username : <input id="username" type="text" /><br>
                Password : <input id="password" type="password" /><br>
                <input id="submit" type="submit" />
                <input id="reset" type="reset" />
            </form>
        </div>
    </body>
</html>

HTML parsing is very simple with Jsoup, all you need to call is the static method Jsoup.parse()and pass your HTML String to it. JSoup provides several overloaded parse() method to read HTML files from String, a File, from a base URI, from an URL, and from an InputStream. You can also specify character encoding to read HTML files correctly in case they are not in “UTF-8” format.

JSoup read web site’s title

In the following example, we scrape and parse a web page and retrieve the
content of the title element.

com/zetcode/JSoupTitleEx.java

package com.zetcode;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JSoupTitleEx {

    public static void main(String[] args) throws IOException {
        
        String url = "http://webcode.me";
        
        Document doc = Jsoup.connect(url).get();
        String title = doc.title();
        System.out.println(title);
    }
}

In the code example, we read the title of a specified web page.

Document doc = Jsoup.connect(url).get();

The Jsoup’s method creates a connection to
the given URL. The method executes a GET request
and parses the result; it returns a HTML document.

String title = doc.title();

With the document’s method, we get the title
of the HTML document.

Платный сервис в заключении

В заключении расскажу о сервисе парсинга для развитием которого я занимаюсь — iDatica. Мы делаем разработку парсеров и сопровждающих услуг: очищаем данные, сопоставляем (матчим) товары, визуализируем информацию в Bi сервисах, делаем это качественно, под ключ.

Мы не предлагаем бесплатный тариф, почему наши услуги нужны, если есть готовые и даже бесплатные сервисы? Если кратко, для работы с сервисами-продуктами требуются сотрудники, которые будут с ними работать, требуется время на изучение функциональности, более того не во всех случаях способны справиться с парсингом нужных сайтов.

Если говорить более развернуто — мы поможем, когда продукт, не может собрать данные с нужного сайта, например, большинство даже платных версий сервисов из списка, при тестировании не справились с парсингом Яндекс.Маркет, а тем или иным способом защищаются от парсинга многие коммерческие сайты. Мы напишем логику парсинга под ваши требования, например, сначала найти на сайте нужную информацию, выбрать категории, бренды, парсинг набора ссылок или парсинг сайта с нестандартной структурой. Мы сравним ваши товары и товары конкурентов с максимальной точностью, в противовес — автоматические алгоритмы сравнения товаров часто не отрабатывают на 100% и требуют ручной доработки с вашей стороны, а часть сервисов потребует предварительно сопоставить ваши товары и товары конкурентов, а если какие-то адреса карточек изменяться, делать это придется заново. Все это выливается в оплату сервиса, оплату труда сотрудника, который работает с сервисом, а если сервис в конечном итоге не справится, в потраченное время и необходимость искать новый сервис. Выбирая работу с нами, вы просто будете получать нужный результат в готовом виде.

What is JSoup Library

Jsoup is an open source Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods. Jsoup implements the WHATWG HTML5 specification, and parses HTML to the same DOM as modern browsers like Chrome and Firefox do. Here are some of the useful features of jsoup library :

  •     Jsoup can scrape and parse HTML from a URL, file, or string
  •     Jsoup can find and extract data, using DOM traversal or CSS selectors
  •     Jsoup allows you to manipulate the HTML elements, attributes, and text
  •     Jsoup provides clean user-submitted content against a safe white-list, to prevent XSS attacks
  •     Jsoup also output tidy HTML

Jsoup is designed to deal with different kinds of HTML found in the real world, which includes properly validated HTML to incomplete non-validate tag collection. One of the core strengths of Jsoup is that it’s very robust.

Modifying

Modifying encompasses setting attributes, text, and HTML of elements, as well as appending and removing elements. It is done to the DOM tree previously generated by jsoup – the Document.

7.1. Setting Attributes and Inner Text/HTML

As in jQuery, the methods to set attributes, text, and HTML bear the same names but also receive the value to be set:

  • attr() – sets an attribute’s values (it creates the attribute if it does not exist)
  • text() – sets element inner text, replacing content
  • html() – sets element inner HTML, replacing content

Let’s look at a quick example of these methods:

7.2. Creating and Appending Elements

To add a new element, you need to build it first by instantiating Element. Once the Element has been built, you can append it to another Element using the appendChild method. The newly created and appended Element will be inserted at the end of the element where appendChild is called:

7.3. Removing Elements

To remove elements, you need to select them first and run the remove method.

For example, let’s remove all <li> tags that contain the “navbar-link” class from Document, and all images from the first article:

7.4. Converting the Modified Document to HTML

Finally, since we were changing the Document, we might want to check our work.

To do this, we can explore the Document DOM tree by selecting, traversing, and extracting using the presented methods, or we can simply extract its HTML as a String using the html() method:

The String output is a tidy HTML.

Java Program to parse HTML Document

Here is our complete Java program to parse an HTML String, an HTML file downloaded from the internet and an HTML file from the local file system. In order to run this program, you can either use the Eclipse IDE or you can just use any IDE or command prompt. In Eclipse, it’s very easy, just copy this code, create a new Java project, right click on src package and paste it. Eclipse will take care of creating proper package and Java source file with same name, so absolutely less work. If you already have a Sample Java project, then it’s just one step. Following Java program shows 3 examples of parsing and traversing HTML file. In first example, we directly parse an String with html content, in the second example we parse an HTML file downloaded from an URL, in the third example we load and parse an HTML document from local file system.

import java.io.File;
import java.io.IOException;
 
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
 
/**
* Java Program to parse/read HTML documents from File using Jsoup library.
* Jsoup is an open source library which allows Java developer to parse HTML
* files and extract elements, manipulate data, change style using DOM, CSS and
* JQuery like method.
*
* @author Javin Paul
*/
public class HTMLParser{
 
    public static void main(String args[]) {
 
        // Parse HTML String using JSoup library
        String HTMLSTring = "<!DOCTYPE html>"
                + "<html>"
                + "<head>"
                + "<title>JSoup Example</title>"
                + "</head>"
                + "<body>"
                + "<table><tr><td><h1>HelloWorld</h1></tr>"
                + "</table>"
                + "</body>"
                + "</html>";
 
        Document html = Jsoup.parse(HTMLSTring);
        String title = html.title();
        String h1 = html.body().getElementsByTag("h1").text();
 
        System.out.println("Input HTML String to JSoup :" + HTMLSTring);
        System.out.println("After parsing, Title : " + title);
        System.out.println("Afte parsing, Heading : " + h1);
 
        // JSoup Example 2 - Reading HTML page from URL
        Document doc;
        try {
            doc = Jsoup.connect("http://google.com/").get();
            title = doc.title();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        System.out.println("Jsoup Can read HTML page from URL, title : " + title);
 
        // JSoup Example 3 - Parsing an HTML file in Java
        //Document htmlFile = Jsoup.parse("login.html", "ISO-8859-1"); // wrong
        Document htmlFile = null;
        try {
            htmlFile = Jsoup.parse(new File("login.html"), "ISO-8859-1");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } // right
        title = htmlFile.title();
        Element div = htmlFile.getElementById("login");
        String cssClass = div.className(); // getting class form HTML element
 
        System.out.println("Jsoup can also parse HTML file directly");
        System.out.println("title : " + title);
        System.out.println("class of div tag : " + cssClass);
    }
 
}
Output:
Input HTML String to JSoup :<!DOCTYPE html><html><head><title>JSoup Example</title></head><body><table><tr><td><h1>HelloWorld</h1></tr></table></body></html>
After parsing, Title : JSoup Example
Afte parsing, Heading : HelloWorld
Jsoup Can read HTML page from URL, title : Google
Jsoup can also parse HTML file directly
title : Login Page
class of div tag : simple

The Jsoup HTML parser will make every attempt to create a clean parse from the HTML you provide, regardless of whether the HTML is well-formed or not. It can handle the following mistakes :
unclosed tags (e.g. <p>Java <p>Scala to <p>Java</p> <p>Scala</p>)
implicit tags (e.g.a naked <td>Java is Great</td> is wrapped into a <table><tr><td>)
reliably creating the document structure (html containing a head and body, and only appropriate elements within the head).

Jsoup is an excellent and robust open source library which makes reading html documents, body fragments, html strings and directly parsing html content from the web, extremely easy.

Reference: 3 Examples of Parsing HTML File in Java using Jsoup from our JCG partner Javin Paul at the Javarevisited blog.

Loading

The loading phase comprises the fetching and parsing of the HTML into a Document. Jsoup guarantees the parsing of any HTML, from the most invalid to the totally validated ones, as a modern browser would do. It can be achieved by loading a String, an InputStream, a File or a URL.

Let’s load a Document from the Spring Blog URL:

Notice the get method, it represents an HTTP GET call. You could also do an HTTP POST with the post method (or you could use a method which receives the HTTP method type as a parameter).

If you need to detect abnormal status codes (e.g. 404), you should catch the HttpStatusException exception:

Sometimes, the connection needs to be a bit more customized. Jsoup.connect(…) returns a Connection which allows you to set, among other things, the user agent, referrer, connection timeout, cookies, post data, and headers:

Since the connection follows a fluent interface, you can chain these methods before calling the desired HTTP method:

You can learn more about the Connection settings by browsing the corresponding Javadoc.

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
Добавить комментарий