Как написать парсер на java
Перейти к содержимому

Как написать парсер на java

  • автор:

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

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

Обновлено: 2022-09-21 17:46:09 СМ Сергей Марочканич автор материала

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

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

Инструменты

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

 net.sourceforge.htmlunit htmlunit 2.19 

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

Разработка java игр была особенно популярна на мобильных телефонах начальных поколений.

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

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

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

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

Теперь откройте среду разработки. Пришло время писать код. Для выполнения запроса в 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=" rel="nofollow noopener noreferrer" target="_blank">https://newyork.craigslist.org/search/sss?sort=rel&query=" + URLEncoder.encode(searchQuery, "UTF-8"); HtmlPage page = client.getPage(searchUrl); >catch(Exception e) < e.printStackTrace(); >>

Редактировать XML файл можно с помощью текстового редактора или специализированного ПО.

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

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

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

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

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

Сначала нужно выбрать все теги

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

List items = (List) 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)); >>

Среда программирования Java предоставляет разработчикам инструменты для написания и тестирования кода.

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

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

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

 com.fasterxml.jackson.core jackson-databind 2.7.0 

Теперь нужно создать элемент, задать атрибуты, конвертировать в строку или файл 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); >

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

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

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

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

Как написать парсер на java

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

Вот некоторые шаги и подходы, которые могут помочь в написании парсера на Java :

  • Определить формат данных, которые нужно распарсить. Например, это может быть формат JSON , XML , CSV или другой формат.
  • Использовать соответствующие библиотеки для парсинга данных. Например, для парсинга JSON-данных можно использовать библиотеку Jackson или Gson , для парсинга XML-данных можно использовать библиотеку JAXB или DOM , для парсинга CSV-данных можно использовать библиотеку OpenCSV и т.д.
  • Определить структуру данных, в которую будут сохраняться распарсенные данные. Например, для JSON-данных это может быть объект класса, для XML-данных это может быть DOM-дерево или объекты, сгенерированные из схемы XML , для CSV-данных это может быть список объектов.
  • Написать код, который будет использовать выбранную библиотеку для чтения данных из файла или другого источника, и сохранять их в соответствующую структуру данных.

Например, вот пример кода для чтения и распарсивания JSON-данных с помощью библиотеки Jackson :

ObjectMapper objectMapper = new ObjectMapper(); File file = new File("data.json"); MyDataObject myDataObject = objectMapper.readValue(file, MyDataObject.class); 

Здесь MyDataObject — это класс, который соответствует структуре JSON-данных . Метод readValue() преобразует данные из файла в объект класса MyDataObject

Вот еще пример кода для чтения и распарсивания XML-данных с помощью библиотеки JAXB :

JAXBContext jaxbContext = JAXBContext.newInstance(MyDataObject.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); File file = new File("data.xml"); MyDataObject myDataObject = (MyDataObject) unmarshaller.unmarshal(file); 

Здесь MyDataObject — это класс, который соответствует структуре XML-данных . Метод unmarshal() преобразует данные из файла в объект класса MyDataObject

Надеюсь, эти примеры помогут вам начать работу с написанием парсера на Java !

Как парсить в java

Парсинг (анализ) данных в Java подразумевает чтение структурированной информации из файлов, строк, потоков или сети и преобразование этой информации в объекты Java . Для парсинга используются различные библиотеки, такие как Jackson , Gson , XMLPullParser , Jsoup и т.д.

Для примера рассмотрим парсинг данных в формате JSON в Java с использованием библиотеки Jackson с помощью Gradle :

  • Добавьте зависимость Jackson в файл build.gradle :
dependencies  implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.5' > 
  • Создайте POJO-класс , который соответствует структуре JSON-файла . Например, если ваш JSON-файл имеет следующую структуру:
 "id": 1, "name": "John Doe", "email": "johndoe@example.com" > 

то класс может выглядеть следующим образом:

public class User  private int id; private String name; private String email; // Геттеры и сеттеры public int getId()  return id; > public void setId(int id)  this.id = id; > public String getName()  return name; > public void setName(String name)  this.name = name; > public String getEmail()  return email; > public void setEmail(String email)  this.email = email; > > 
  • Создайте объект ObjectMapper , который является основным классом для обработки JSON-данных в Jackson :
ObjectMapper objectMapper = new ObjectMapper(); 
  • Используйте метод readValue() для чтения JSON-файла и преобразования его в объект Java :
File file = new File("user.json"); User user = objectMapper.readValue(file, User.class); 

Метод readValue() принимает два параметра: File и класс, в который должны быть преобразованы данные из JSON-файла

Теперь вы можете использовать объект user , чтобы получить доступ к данным из JSON-файла

Лёгкий парсинг HTML с помощью jsoup

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

Быстрый старт

Библиотеку можно скачать в виде jar файла и поместить в проект, а также подключить с помощью Maven/Gradle. Ссылку на официальный сайт я оставлю в конце статьи: там вы сможете найти актуальную версию библиотеки. В примере будем использовать подключение через Maven. Добавим зависимость:

  org.jsoup jsoup 1.11.3  

Использование

Первым делом вам необходимо получить экземпляр класса Document из org.jsoup.nodes.Document с указанием на источник для разбора. Им может выступать как локальный файл, так и ссылка. Для примера, в данной статье мы будем использовать сайт yandex.ru и попытаемся получить их актуальную новостную ленту:

Java-университет

 Document doc = Jsoup.connect("https://yandex.ru/") .userAgent("Chrome/4.0.249.0 Safari/532.5") .referrer("http://www.google.com") .get(); 

Лёгкий парсинг HTML с помощью jsoup - 1

User Agent является идентификатором, который сообщается посещаемому сайту. На многих сайтах он является важнейшим критерием для антиспам фильтра. Referrer содержит URL источника запроса. Метод get() вызывает обрабатываемое исключение IOException, так что мы можем обернуть все в try/catch блок, либо просто перебросить его дальше с помощью throws . На данный момент мы получили исходный код данной страницы. При необходимости библиотека jsoup сама может восстановить поврежденные элементы. Теперь нам остается лишь сузить поиск до отдельного блока. Метод select() имеет большую выборку в использовании: он позволяет искать элементы по тегу, атрибутам, классу и другим параметрам. Почти все современные браузеры поддерживают возможность быстрого поиска исходного кода выбранного элемента. Нехитрыми манипуляциями, мы находим исходный код нужного нам элемента и получаем div блок с указанным классом, его мы и будем использовать для выборки. Воспользуемся классом Elements из org.jsoup.select.Elements, для выборки всех элементов из нашего выбранного блока.

 Elements listNews = doc.select("div#tabnews_newsc.content-tabs__items.content-tabs__items_active_true"); 

Лёгкий парсинг HTML с помощью jsoup - 2

Сейчас мы имеем что то вроде этого: Теперь нам остается лишь использовать небольшой цикл для пробора всех элементов:

 for (Element element : listNews.select("a")) System.out.println(element.text()); 

Лёгкий парсинг HTML с помощью jsoup - 3

Метод text() позволяет отбросить код разметки и оставляет лишь сочетание текста для всех входящих элементов. Результат выполнения будет таков: Нетрудно заметить, что реальное количество полученных строк не соответствует фактическому отображению на странице. В этом и заключаются подводные камни. Если посмотреть исходный код разметки, можно заметить, что последняя новость анимационно меняется с определенным интервалом времени. Часть таких «камней» решается дополнительной выборкой, ну и конечно тестами. Может оказаться так, что первые пять элементов будут содержать нужную нам информацию, а на шестом элементе будет лишь заскриптованная пустая строка. Бывает и такое, что блоки не будут обладать какими-либо идентификаторами, тогда есть возможностью прямо указать с помощью метода get(int index) на номер позиции рассматриваемого элемента.

 System.out.println(listNews.select("a").get(2).text()); 

Заключение

В данном примере показана лишь малая часть того, на что способен jsoup. Не стоит отменять и тот факт, что сайты нередко обновляются, изменяя структуру кода разметки, так что при работе с парсингом нужно быть готовым адаптироваться к изменениям. Больше информации и актуальную версию вы можете получить на официальном сайте jsoup.org, более подробно почитать про классы и методы можно по ссылке o7planning.org. Оставлю ссылку на мой github, на момент написания статьи там находится несколько Telegram-ботов, которые используют Jsoup для получения и выдачи информации.

Добавить комментарий

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