Веб-скрапинг необходим для сбора больших структурированных наборов данных из Интернета для таких целей, как бизнес-аналитика, исследования, журналистика данных и т. д. Хотя Python и JavaScript являются популярными языками для парсинга, Java предоставляет надежные библиотеки, поддержку многопоточности и независимость от платформы, что делает его отличным выбором для парсеров промышленного уровня.
В этом подробном руководстве мы рассмотрим, как использовать Java для создания веб-скраперов, а также примеры кода и лучшие практики.
Зачем использовать Java для парсинга веб-страниц?
Давайте сначала разберемся с некоторыми ключевыми преимуществами использования Java для парсинга веб-страниц:
- Зрелый язык – Java статически типизирован, объектно-ориентирован и существует уже несколько десятилетий. Отлично подходит для создания больших, удобных в обслуживании скребков.
- Отличные библиотеки – Предоставляет такие библиотеки, как JСуп и ХтмлЮнит разработан специально для парсинга и очистки HTML.
- Независимость от платформы – Код Java компилируется в байт-код, который работает в любой ОС. Скребки могут работать на Windows, Linux, Mac и т. д.
- Поддержка многопоточности – Скребки могут использовать потоки и асинхронные запросы для достижения очень высокой пропускной способности.
- Корпоративная интеграция – Легко интегрировать парсеры, написанные на Java, с такими базами данных, как SQL, NoSQL, платформами больших данных для хранения извлеченных данных.
- Инструменты – Зрелые IDE, среды тестирования, ведение журналов и инструменты сборки делают разработку продуктивной.
Таким образом, для команд, уже использующих Java, создание парсеров на Java помогает повторно использовать существующие навыки и код. В соответствии с Опросы StackOverflowJava неизменно остается одним из самых популярных языков среди разработчиков, что способствует набору персонала.
Язык | Опрос разработчиков 2021 г. |
---|---|
JavaScript | 41.7% |
HTML / CSS | 38.9% |
SQL | 37.4% |
Питон | 37.2% |
Java | 31.4% |
Теперь давайте посмотрим, как парсинг веб-страниц реализован в Java.
Ключевые компоненты Java Web Scraper
Хотя точная архитектура парсеров зависит от варианта использования, большинство веб-парсеров Java имеют следующие ключевые компоненты:
- HTTP-клиент – Для отправки запросов и получения веб-страниц. Популярные варианты:
HttpClient
,OkHttp
,WebClient
из HtmlUnit. - HTML-парсер – Для анализа полученного содержимого HTML. Парсеры типа
JSoup
иHtmlUnit
обычно используются. - API-интерфейсы обхода DOM – Для навигации по узлам HTML и извлечения данных. Например. Методы JSoup, такие как
select()
,getElementById()
и так далее - Код извлечения данных – Реальная бизнес-логика для извлечения необходимых данных из HTML. Может включать регулярные выражения, манипуляции со строками и т. д.
- Хранение данных – Код для хранения очищенных данных в CSV, JSON, базе данных и т. д. для последующего использования.
- Очередь запросов – Эффективно управлять запросами на большие объемы данных. Очереди, подобные RabbitMQ, помогают координировать работу парсеров.
- Прокси-ротация – Для динамической ротации IP-адресов и предотвращения блокировки. Интеграция с такими инструментами, как Проксиротатор pomaga.
- Браузерная автоматизация – Для сайтов, в значительной степени использующих JavaScript. Безголовые браузеры, такие как HtmlUnit или Selenium, предоставляют доступ к DOM.
Давайте теперь посмотрим, как эти компоненты объединяются в простом парсере JSoup.
Парсинг веб-страниц с помощью JSoup
JСуп — чрезвычайно популярная Java-библиотека с открытым исходным кодом для очистки веб-страниц, анализа и очистки HTML-страниц. Он предоставляет очень удобный API обхода DOM, аналогичный BeautifulSoup в Python.
Давайте создадим базовый парсер для извлечения данных о продуктах со страницы электронной торговли с помощью JSoup:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class JSoupScraper {
public static void main(String[] args) throws IOException {
// Fetch the page
Document doc = JSoup.connect("https://www.example.com/products/iphone-x").get();
// Extract product title
String title = doc.select("h1.product-title").text();
// Extract price
String price = doc.select("span.price").text();
// Extract rating
String rating = doc.select("div.ratings").attr("data-rating");
// Extract image URL
String image = doc.select("img.primary-image").attr("src");
// Print scraped data
System.out.println("Title: " + title);
System.out.println("Price: " + price);
System.out.println("Rating: " + rating);
System.out.println("Image URL: " + image);
}
}
Вот несколько ключевых моментов:
- Сначала мы получаем целевую страницу с помощью
Jsoup.connect()
что дает нам анализируемыйDocument
объект. - JSoup's
select()
позволяет нам использовать селекторы CSS для извлечения элементов. - Вспомогательные методы, такие как
text()
,attr()
давайте удобно получать данные из выбранных элементов. - Мы просто распечатываем здесь извлеченные данные, но обычно вы сохраняете их в базе данных, файле JSON и т. д.
Хотя эта демонстрация извлекает данные с одной страницы, вы можете обернуть ее в цикл для масштабируемого сбора данных с нескольких страниц продукта.
Некоторые другие полезные функции JSoup:
- Обработка файлов cookie и сеансов
- Программное заполнение и отправка форм
- Выполнение POST-запросов вместе с данными
- Парсинг XML, RSS-каналов и другого контента, отличного от HTML.
- Использование пулов соединений для повышения производительности
В целом, JSoup упрощает анализ HTML и извлечение данных в Java. Далее давайте посмотрим на еще одну популярную библиотеку парсинга.
Парсинг веб-страниц с помощью HtmlUnit
ХтмлЮнит — это безголовый браузер для приложений Java. Некоторые из его преимуществ:
- Может отображать JavaScript для взаимодействия с современными SPA и веб-приложениями.
- Предоставляет такие инструменты, как консоль разработчика Firefox, для идентификации элементов.
- Эмулирует действия браузера, такие как нажатие кнопок, заполнение форм и т. д.
Давайте посмотрим простой пример:
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class HtmlUnitScraper {
public static void main(String[] args) throws Exception {
WebClient webClient = new WebClient();
// Fetch the page
HtmlPage page = webClient.getPage("https://www.example.com");
// Extract page title
String title = page.getTitleText();
// Extract H1 element
String h1 = page.getByXPath("//h1").getTextContent();
System.out.println("Title: " + title);
System.out.println("H1: " + h1);
}
}
В дополнение к альтернативным методам обхода DOM, таким как getByXPath()
, HtmlUnit также предоставляет такие действия, как click()
, type()
и т. д., которые очень полезны для автоматизации и очистки сложных SPA.
Приведенные выше примеры дают базовый обзор того, как работает парсинг веб-страниц в Java. Давайте теперь обсудим некоторые передовые методы создания надежных скреперов промышленного уровня.
Лучшие практики для надежных веб-скраперов
Вот несколько рекомендаций, которым я следую для создания быстрых и отказоустойчивых парсеров веб-страниц на Java:
- Ограничение скорости обработки – Используйте прокси, ротацию пользовательских агентов и повторные попытки, чтобы избежать блокировки целевыми сайтами.
- Распараллеливать запросы – Используйте многопоточность и асинхронные запросы через такие библиотеки, как Akka, чтобы сделать парсинг намного быстрее.
- Настроенные HTTP-клиенты – Настройте таймауты, перенаправления и пулы соединений в клиентах, таких как HttpClient, для оптимальной производительности.
- Нулевая проверка – Явно проверяйте наличие отсутствующих или пустых полей и недопустимых данных, чтобы избежать исключений NullPointerException.
- Запись – Регистрируйте ошибки, метрики, HTTP-вызовы с помощью Log4j2 или Logback для быстрого устранения проблем.
- Пакетные вставки данных – Пакетная вставка и загрузка базы данных с использованием Spring JDBC для гораздо более высокой пропускной способности.
- Модульный код – Соблюдайте разделение обязанностей. Экстернализация URL-адресов, селекторов и правил для легкой настройки парсеров.
- Модульное тестирование – Напишите тестовые примеры JUnit, чтобы выявить регрессии при изменении веб-сайтов.
- Облачное развертывание – Дешево масштабируйте парсеры по горизонтали, развертывая их на облачных платформах, таких как AWS.
Используя эти передовые методы и возможности Java, вы можете создавать сканеры корпоративного уровня для крупномасштабного производственного использования. Далее давайте обсудим некоторые сложные темы.
Очистка JavaScript SPA и сканеров
Современные веб-сайты в значительной степени полагаются на фреймворки JavaScript, такие как React и Vue, для динамического отображения контента. Хотя инструменты старой школы могут потерпеть неудачу, вот два варианта парсинга страниц JavaScript с помощью Java:
Автоматизация браузера с помощью Selenium
Ассоциация Селен Платформа тестирования браузеров имеет привязки Java, которые позволяют программно управлять такими браузерами, как Chrome и Firefox. Это помогает очищать динамический контент, созданный с помощью JavaScript.
Вот простой пример:
// Launch headless Chrome browser
ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
WebDriver driver = new ChromeDriver(options);
// Go to URL
driver.get("https://www.example.com");
// Wait for content to render
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".dynamic-element")));
// Extract text
String elementText = driver.findElement(By.cssSelector(".dynamic-element")).getText();
// Close browser
driver.quit();
Хотя Selenium предоставляет удобный способ очистки SPA, производительность относительно медленнее по сравнению с прямыми HTTP-запросами.
Безголовые браузеры, такие как HtmlUnit
Как было показано ранее, HtmlUnit может эмулировать автономный браузер и самостоятельно выполнять JavaScript без необходимости использования реального браузера. Производительность намного лучше по сравнению с Selenium.
Такие инструменты, как TrifleJS и Браузер марионеток есть другие варианты для оценки.
Для крупномасштабного сканирования веб-страниц, а не просто для сканирования нескольких страниц, я рекомендую специальный высокопроизводительный сканер, например Апач Натч. Он предназначен для очистки всей сети и может интегрироваться с Solr или Elasticsearch для полнотекстового индексирования.
Хранение очищенных данных
Есть несколько хороших вариантов хранения очищенных данных в Java:
- CSV – Самый простой вариант хранения в формате CSV, который можно импортировать в другие инструменты.
- JSON – Легкий формат, особенно при очистке API или обмене данными.
- MySQL, Постгрес – Для структурированных реляционных данных, требующих сложных запросов.
- MongoDB – Отлично подходит для полуструктурированных данных и документов JSON.
- Elasticsearch – Для полнотекстового поиска и аналитики больших наборов данных.
Вот пример сохранения данных в CSV с использованием OpenCSV:
import com.opencsv.CSVWriter;
String csvFile = "/data.csv";
CSVWriter writer = new CSVWriter(new FileWriter(csvFile));
String[] headers = {"title", "price", "rating"};
writer.writeNext(headers);
String[] row1 = {"iPhone X", "$999", "4.5"};
writer.writeNext(row1);
String[] row2 = {"Pixel 2", "$699", "4.3"};
writer.writeNext(row2);
writer.close();
Аналогично, такие библиотеки, как Mongo Java Driver, JDBC, синтаксический анализатор Джексона, можно использовать для сохранения данных в базы данных и JSON.
Сквозной пример
Давайте теперь создадим сквозной парсер на Java для извлечения списков телефонов со страницы каталога и сохранения в CSV.
Целевая страница
Наш парсер извлечет номера телефонов, имя, адрес и сохранит их в файл CSV.
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;
public class PhoneDirectoryScraper {
public static void main(String[] args) throws IOException {
String url = "https://example.com/directory";
String csvFile = "/data.csv";
// Fetch HTML
Document doc = Jsoup.connect(url).get();
// Select all listings
Elements listings = doc.select(".listing");
// Open CSV writer
CSVWriter writer = new CSVWriter(new FileWriter(csvFile));
// Write headers
String[] headers = {"name", "address", "phone"};
writer.writeNext(headers);
// Loop through listings
for(Element listing : listings) {
// Extract data
String name = listing.select(".name").text();
String address = listing.select(".address").text();
String phone = listing.select(".phone").text();
// Write row
String[] row = {name, address, phone};
writer.writeNext(row);
}
// Close writer
writer.close();
}
}
Он реализует полноценный парсер для извлечения структурированных данных с веб-страницы и сохранения в формате CSV с использованием простых селекторов JSoup и библиотеки OpenCSV.
То же самое можно распространить на парсинг нескольких страниц, заключив в цикл разные URL-адреса. Вы также можете улучшить парсер с помощью многопоточности, прокси, пользовательских агентов и облачного развертывания для крупномасштабного сканирования.
Заключение
Java предоставляет множество надежных библиотек и возможностей для создания высокопроизводительных веб-скребков. Благодаря мощной поддержке многопоточности, независимости от платформы и широкому использованию языков Java является отличным выбором для парсинга промышленного уровня в 2024 году и в последующий период.
Мы обсудили основы парсинга веб-страниц на Java и увидели примеры кода с использованием популярных библиотек, таких как JSoup и HtmlUnit. Мы также рассмотрели лучшие практики, такие как обработка прокси, повторные попытки, настройка HTTP-клиентов и распараллеливание, чтобы сделать парсеры более быстрыми и устойчивыми. Наконец, мы рассмотрели сквозной парсер для извлечения списков телефонов в файл CSV.
Приведенные здесь примеры должны дать хороший обзор того, как начать парсинг веб-страниц на Java. Для вашего конкретного случая использования вы можете дополнительно изучить различные библиотеки, такие как Web Harvester, Apache Nutch и т. д., и создать более индивидуальное решение.
Кроме того, вместо того, чтобы создавать все с нуля, такие платформы, как СкребокAPI предоставить облачные прокси, браузеры и инфраструктуру для упрощения выполнения крупномасштабных заданий по очистке данных.
Я надеюсь, что это руководство дало вам полное представление о парсинге веб-страниц с использованием Java в 2024 году! Дайте мне знать, если у вас есть еще вопросы.