перейти к содержанию

Парсинг веб-страниц с помощью Java: комплексное руководство на 2024 год для начинающих и экспертов

Веб-скрапинг необходим для сбора больших структурированных наборов данных из Интернета для таких целей, как бизнес-аналитика, исследования, журналистика данных и т. д. Хотя Python и JavaScript являются популярными языками для парсинга, Java предоставляет надежные библиотеки, поддержку многопоточности и независимость от платформы, что делает его отличным выбором для парсеров промышленного уровня.

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

Зачем использовать Java для парсинга веб-страниц?

Давайте сначала разберемся с некоторыми ключевыми преимуществами использования Java для парсинга веб-страниц:

  • Зрелый язык – Java статически типизирован, объектно-ориентирован и существует уже несколько десятилетий. Отлично подходит для создания больших, удобных в обслуживании скребков.
  • Отличные библиотеки – Предоставляет такие библиотеки, как JСуп и ХтмлЮнит разработан специально для парсинга и очистки HTML.
  • Независимость от платформы – Код Java компилируется в байт-код, который работает в любой ОС. Скребки могут работать на Windows, Linux, Mac и т. д.
  • Поддержка многопоточности – Скребки могут использовать потоки и асинхронные запросы для достижения очень высокой пропускной способности.
  • Корпоративная интеграция – Легко интегрировать парсеры, написанные на Java, с такими базами данных, как SQL, NoSQL, платформами больших данных для хранения извлеченных данных.
  • Инструменты – Зрелые IDE, среды тестирования, ведение журналов и инструменты сборки делают разработку продуктивной.

Таким образом, для команд, уже использующих Java, создание парсеров на Java помогает повторно использовать существующие навыки и код. В соответствии с Опросы StackOverflowJava неизменно остается одним из самых популярных языков среди разработчиков, что способствует набору персонала.

ЯзыкОпрос разработчиков 2021 г.
JavaScript41.7%
HTML / CSS38.9%
SQL37.4%
Питон37.2%
Java31.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 году! Дайте мне знать, если у вас есть еще вопросы.

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *