Создаем парсер на Java

Парсинг сайтов с помощью Java – это мощный инструмент для сбора данных с веб-страниц. В статье рассматриваются основные подходы и библиотеки, которые помогут вам создать эффективный парсер для различных сайтов.

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

СМ Сергей Марочканичавтор материала

Обязательные условия

  • Базовые знания Java;
  • Основы XPath.

Инструменты

Вам потребуется Java 8 и браузер HtmlUnit

<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.19</version>
</dependency>

Если вы используете Eclipse, советую изменить максимальную длину в окне подробностей (при нажатии на вкладку «Переменные»), чтобы можно было видеть весь HTML-код веб-страницы.

Инструменты

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

В примере парсинга сайта Java мы извлечем информацию с интернет-магазина. Соберем имена, цены, а также картинки и экспортируем их в формат JSON.

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

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

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[@class='result-info']" ;
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[@class='result-price']")) ;
// Возможно, что для товара не установлена цена
String itemPrice = spanPrice == null ? "no price" : spanPrice.asText() ;
System.out.println( String.format("Name : %s Url : %s Price : %s", itemName, itemPrice, itemUrl));
}
}

Затем сохраним данные в формате JSON, используя библиотеку Jackson. Для представления элементов, полученных при парсинге email адресов с сайта, нам понадобится POJO (объект языка Java ).

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[@class='txt']/span[@class='pl']/a"));
HtmlElement spanPrice = ((HtmlElement) htmlItem.getFirstByXPath(".//span[@class='txt']/span[@class='l2']/span[@class='price']")) ;
// Возможно, для товара не установлена цена, в этом случае мы обозначаем ее как 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);
}

Не останавливайтесь

Этот пример парсинга другого сайта не идеален, многое можно улучшить:

  • Поиск по городам;
  • Обработка пагинации;
  • Поиск по нескольким критериям.

Код примера находится здесь.

СМ Сергей Марочканичавтор статьи «Introduction to Web scraping with Java»

Комментарии

Оставьте свой комментарий
Ильдар К.

Позор!
Чел даже ссылку в searchUrl не мог нормально поместить.

ВК
Владимир К.

Ошибки в изначальной статье и в этом переводе.
Вот эта строчка даже компиляцию не пройдет:
List<HtmlElement> items = (List<HtmlElement>) page.getByXPath("//p[@class='result-info']" ;

Д

добавь скобку и всего делов )

М
Михаил

...огромная просьба к г.г. программистам - выносить юмор за скобки.
И так ни хрена не понятно...