Почему Java, а не Python? (Спойлер: выбор не очевиден)
Когда речь заходит о парсинге и скрапинге данных, в голову чаще всего приходит Python с его BeautifulSoup и Scrapy. Но давайте честно: в мире enterprise-разработки, высоконагруженных систем и микросервисов Java остаётся королём. Если вы уже пишете на Java или только присматриваетесь к этому языку, то парсинг на нём — это не просто «можно», а зачастую и нужно: высокая скорость, встроенная многопоточность, мощные инструменты для работы с HTTP и HTML.
В этой статье мы разберём, как парсить сайты на Java с нуля. Вы узнаете, какие библиотеки использовать, как не попасть под бан и как собрать свой первый рабочий парсер. Примеры кода будут максимально живыми — берите и запускайте.
Что такое парсинг и скрапинг данных (и зачем это вам)
Прежде чем нырять в код, давайте разберёмся с терминами. Парсинг — это разбор структуры (HTML, JSON, XML) и извлечение нужной информации. Скрапинг — это процесс сбора данных с веб-страниц, который включает и парсинг, и загрузку страниц, и обход ссылок.
Зачем это нужно? Примеры из реальной жизни:
- Мониторинг цен конкурентов (сбор данных с интернет-магазинов).
- Сбор контактов и email-адресов для B2B-лидогенерации.
- Автоматизация сбора новостей или постов из соцсетей.
- Анализ отзывов и рейтингов товаров.
На Java всё это делается быстро, стабильно и с минимальным потреблением памяти.
Инструментарий Java для парсинга: выбираем библиотеки
Для парсинга и скрапинга данных на Java есть несколько мощных библиотек. Вот основной набор, который покроет 95% задач:
- Jsoup — главная библиотека для парсинга HTML. Умеет ходить на сайты, выдёргивать элементы по CSS-селекторам, работать с атрибутами и текстом.
- Apache HttpClient или Java 11+ HttpClient — для тонкой настройки запросов, работы с куками, сессиями и заголовками.
- Selenium WebDriver — если сайт использует JavaScript для подгрузки данных. Рендерит страницу как настоящий браузер (Chrome, Firefox).
- OkHttp — лёгкая и быстрая альтернатива HttpClient.
Для большинства статических сайтов достаточно Jsoup + встроенного HttpClient. Для динамических — добавляем Selenium.
Пишем первый парсер на Java с Jsoup
Начнём с простого: спарсим заголовки статей с блога. Допустим, нам нужно собрать все заголовки с главной страницы pythonlib.ru (гипотетически).
Подключим зависимость в Maven (pom.xml):
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
Теперь сам код:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class SimpleParser {
public static void main(String[] args) {
try {
// 1. Загружаем страницу
Document doc = Jsoup.connect("https://pythonlib.ru")
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.timeout(10000)
.get();
// 2. Выбираем все заголовки h2 (или любой другой селектор)
Elements headlines = doc.select("h2.entry-title a");
// 3. Выводим текст и ссылки
for (Element headline : headlines) {
String title = headline.text();
String link = headline.attr("href");
System.out.println("Заголовок: " + title);
System.out.println("Ссылка: " + link);
System.out.println("---");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Этот код делает GET-запрос, парсит HTML и выводит заголовки. Обратите внимание на userAgent — без него многие сайты отдают 403 ошибку.
Работа с селекторами: как вытащить нужные данные
Jsoup использует CSS-селекторы, как в jQuery. Вот несколько полезных примеров:
div.content p— все параграфы внутри блока с классом content.#main-article— элемент с id="main-article".a[href*="download"]— все ссылки, содержащие в href слово "download".ul.list li:first-child— первый элемент списка.
Совет: всегда сначала смотрите структуру страницы через инспектор браузера (F12). Это сэкономит часы отладки.
Продвинутый парсинг: имитация браузера и обход блокировок
Реальные сайты часто защищаются от парсинга: проверяют User-Agent, Referer, куки, используют капчу или Cloudflare. Вот как с этим бороться на Java:
1. Настройка заголовков и сессий
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpClient.Redirect;
public class AdvancedHttpClient {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newBuilder()
.followRedirects(Redirect.NORMAL)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.header("Accept-Language", "ru-RU,ru;q=0.9,en;q=0.8")
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
String html = response.body();
// Теперь передаём HTML в Jsoup
Document doc = Jsoup.parse(html);
System.out.println(doc.title());
}
}
2. Работа с куками и сессиями
Если сайт требует авторизации, сначала отправьте POST-запрос с логином/паролем, сохраните куки и используйте их в следующих запросах. Jsoup умеет хранить куки автоматически, если использовать один и тот же объект Connection.
// Пример с сохранением сессии
Document loginPage = Jsoup.connect("https://example.com/login")
.data("username", "user", "password", "pass")
.method(org.jsoup.Connection.Method.POST)
.execute()
.parse();
// Теперь используем ту же сессию для парсинга защищённых страниц
Document profilePage = Jsoup.connect("https://example.com/profile")
.cookies(loginPage