Около месяца назад я решил покинуть дом компании и поискать новый, где я мог бы иметь воздух для себя. Я сказал себе, что поиск вручную на веб-сайтах утомителен, потому что у большого парня в Токио так много вариантов. В конце концов, я подумал, что должен использовать этот шанс, чтобы сделать две вещи:

. Создайте парсер веб-сайтов, чтобы получить все данные с одного из основных сайтов по аренде жилья в Токио и сэкономить мое время.

. Улучшите свои навыки Java, создав этот парсер веб-сайтов. (я знаю, что парсинг веб-сайтов с помощью Python намного проще, не многие люди используют для этого Java)

Веб-сайт, который я нашел, — это GGhouse, один из самых известных веб-сайтов по аренде жилья в Токио. У них очень много домов, которые мы можем очистить.

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

Давайте начнем!

В весенней загрузке, как и в каждом проекте, прежде чем что-либо делать, нам нужно добавить некоторые необходимые зависимости. Скрапинг не является исключением, мы будем использовать зависимость jsoup, чтобы позаботиться о HTML-коде.

В проекте Maven мы добавим следующий фрагмент в файл pom.xml

<dependency>
  <groupId>org.jsoup</groupId>
  <artifactId>jsoup</artifactId>
  <version>1.13.1</version>
</dependency>

В проекте Gradle мы добавим следующий фрагмент в файл build.gradle

compile group: 'org.jsoup', name: 'jsoup', version: '1.13.1'

Традиционно Scraping работал, извлекая данные из статического HTML-кода. Но несколько лет назад рост использования фреймворков Javascript (таких как Angular, React и Meteor…) сделал традиционный способ не таким простым, как раньше. Эти фреймворки будут использовать Javascript для отображения содержимого HTML-кода. Представить! HTML-код — это тело, в котором нет мяса и костей, Javascript используется для его предоставления (изображения продукта, описание, технические характеристики, видео и т. д.). Таким образом, для веб-сайтов, созданных с помощью одной из этих платформ, ничего не стоит получать только HTML-код.

К сожалению, GGhouse как раз такой сайт. Поэтому нам нужно обращаться по-другому.

Невозможно получить данные прямо из HTML-кода веб-сайта, поэтому вместо этого мы будем вызывать его API. Возвращаемые данные — это то, что нам нужно, но в формате JSON. Итак, мы собираемся сначала очистить и преобразовать его в формат HTML, а затем использовать jsoup для извлечения данных.

Помните, что некоторые веб-сайты автоматически блокируют любой вид скрейпинга, поэтому мы поместим команду sleep между страницами. Это может имитировать более человеческое поведение и не перегружать сайт большим количеством запросов в секунду.

Хорошо, сначала мы проверим его, чтобы увидеть, можно ли получить доступ к веб-сайту.

String api = "https://gghouse.co.jp/en/search/result/"
// body of the Request
String path = "en/search/result.html";  //The path of API
int rent_min = 35000;                   //The minimum renting price
int rent_max = 100000;                  //The maximum renting price
int p = 1;                              //Page one
String gender = "";                     //Not specify gender

Запустите приведенный выше код и посмотрите результат.

Вроде все работает гладко!

Время очистить данные!

Если мы внимательно посмотрим на возвращенные данные, то увидим, что значение ключа properties — это то, что мы хотим получить. Это список тегов ‹a›, каждый тег содержит основную информацию о каждом доме. Не только предыдущая и следующая части этого списка, но мы также видим некоторые ненужные символы. выделить на следующих изображениях.

Чтобы очистить данные, используйте следующий фрагмент кода.

result = result.replace("\\n", "").replace("\\", "").replace("{\"properties\":\"", "");
int pos = html.indexOf(">\"");
result = result.replace(pos.substring(index+1, pos.length()), "");

Посмотрим, что у нас получилось!

Готовьте супы!

Это полезно, если вы знакомы с HTML, но если нет, не волнуйтесь, это не обязательно. Я сделаю это максимально простым.

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

Document doc = Jsoup.parse(html);      // parse HTML
Elements listHouse = doc.select("a");  // get list of <a> tags

Теперь наши данные представляют собой объект, который содержит список тегов элемента данных ‹a›. Как я уже говорил, каждый тег ‹a› содержит основную информацию о каждом доме. Итак, сначала определите данные, которые нам нужно получить для каждого дома. После этого, перебирая весь список, мы получим все данные.

Давайте проверим, как мы получаем данные из одного элемента данных (тег ‹a›).

Element item = listHouse.get(1);  // get 2nd data element from list

Ссылка на Дом указывается атрибутом href.

String href = item.attr("href");

Цена дома находится в теге ‹p›. В элементе данных есть только один тег ‹p›.

String price = item.select("p").text(); 

Название факультета находится в первом теге ‹dt›. Итак, сначала мы получим список тегов ‹dt› элемента данных, первый элемент этого списка — это то, что нам нужно.

String name = item.select(“dt”).first().text();

Статус дома указан в первом теге ‹span›. Так же, как и выше.

String status = item.select("span").first().text();

На самом деле мы также получим тип Хауса. это означает, что дом только для женщин или нет. Вы не видите на изображении выше, потому что на нем нет данных. Если да, то тип дома находится во втором теге ‹span.

String type = (item.select(“span”).size() > 1) ? “Women-only” : “”;

Хорошо, давайте посмотрим весь код, который очищает некоторые страницы.

На данный момент мы почти заканчиваем парсинг. Не знаю, заметили ли вы, что выше я упомянул основную информацию о доме. Так что насчет деталей? У нас есть ссылка на дом, верно? давайте получим к нему доступ и очистим.

Получить данные из статического HTML

Доступ к домашней ссылке, мы можем получить данные прямо из статического HTML-кода, не нужно вызывать API.

мы также сначала протестируем его, чтобы увидеть, можно ли получить доступ к веб-сайту.

Responce Code : 200
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>H19 hanasakasu Higashi-nagasaki | Share house GG House Management</title><link rel="icon" href="https://gghouse.co.jp/favicon.ico"><link rel="stylesheet" href="https://gghouse.co.jp/css/style.css"><link rel="stylesheet" href="https://gghouse.co.jp/search/css/pc.css"><link rel="stylesheet" href="https://gghouse.co.jp/search/css/sp.css"><link rel="stylesheet" href="https://gghouse.co.jp/en/search/css/pc.css"><link rel="stylesheet" href="https://gghouse.co.jp/assets/css/front.css" /><link rel="canonical" href="https://gghouse.co.jp/h19/" /><link rel="alternate" hreflang="ja" href="https://gghouse.co.jp/h19/" /><link rel="alternate" hreflang="en" href="https://gghouse.co.jp/en/h19/" /><link rel="alternate" hreflang="zh-hans" href="https://gghouse.co.jp/zh-hans/h19/" /><link rel="alternate" hreflang="ko" hr

Вроде все сделано хорошо.

Как арендатор я считаю, что подробная информация о доме должна включать Описание, Общие помещения, Оборудование помещения и Изображения. Шаг за шагом, сначала мы найдем Description в HTML-коде. Щелкните правой кнопкой мыши веб-страницу и выберите «Проверить».

Мы получим Описание по атрибуту класса, который выделен на изображении выше. Мы также должны очистить его после этого, потому что в нем есть некоторые ненужные символы, как вы можете видеть.

String descriptions = doc.getElementsByClass("text-box container").text();
String characterFilter = "[^\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\s]";
descriptions = descriptions.replaceAll(characterFilter,"");

Мы получим Общие удобстваи Удобства в комнате по атрибуту класса, который выделен на изображении выше. В этом случае возвращаемые данные представляют собой набор, первый элемент данных — Общие удобства,второй — Комнаты. Для удобочитаемости,мы объединяем элементы в каждом учреждении запятой.

Elements facilities = doc.getElementsByClass("ico-list");
StringBuilder share_facility = getFacility(facilities.get(0));
StringBuilder room_facility = getFacility(facilities.get(1));
public StringBuilder getFacility(Element facilities) {
    StringBuilder facility = new StringBuilder();
    String prefix = "";
    for (Element temp : facilities.select("span")) {
        facility.append(prefix);
        prefix = ",";
        facility.append(temp.text());
    }
    return facility;
}

Как видно на изображении выше, каждое изображение дома содержится в теге ‹a›, а этот список тегов ‹a› находится в теге ‹a›. >‹ul id="thumb"›. Итак, сначала мы получим тег ‹ul› по его id, после этого получим href всех тегов ‹a›. Мы объединяем все href с помощью | подписать.

Elements imgs = doc.getElementById("thumb").select("a");
StringBuilder links = new StringBuilder();
String prefix = "";
for (Element item : imgs) {
    links.append(prefix);
    prefix = "|";
    links.append(item.attr("href"));
}

Я всегда думаю о том, следует ли мне загружать изображения или просто получить их ссылку. У меня есть несколько идей, если загрузить все изображения, мне понадобится огромное хранилище. Это очень плохая идея, если один сервер может выполнять множество таких задач (очистка данных, загрузка изображения и т. д.). Поэтому я думаю, что сначала я просто получу ссылку на изображения, возможно, в будущем я создам еще один сервер только для загрузки изображений. Это лучшая идея.

Хорошо, давайте посмотрим весь код, который очищает статический HTML-код.

Бум! мы получили данные!

Очень здорово, если у нас есть служба, которая помогает нам обрабатывать наши данные. Я думаю, что IBM Watson Discovery Service является примером. Я также написал статью об этом сервисе. Если вы хотите посмотреть, я приглашаю вас проверить мою статью https://medium.com/voice-tech-podcast/learn-ibm-watson-discovery-during-the-covid-19-pandemic-727e40fe14e1.

Спасибо всем за чтение!

Посмотрите мой проектhttps://gitlab.com/buingoctruong1508/houseforrent