NodeJs Парсер данных (Часть 1)
Table Of Content
Написание парсера данных может показаться сложной задачей для начинающего программиста, но в современных условиях это действительно просто и не занимает много времени. В то же время это весело и отличный способ собрать данные для вашего проекта.
В этом руководстве я пошагово объясню, как собрать арабские данные из Корана с веб-сайта almaany и записать их в файлы CSV. Поскольку это один из моих проектов, я подумал, что будет хорошей идеей объяснить методы и концепции, лежащие в его основе.
Получение страницы в формате HTML
Сначала мы получим страницу в формате HTML для анализа и тестирования нашего кода. Это совершенно простая и несложная задача благодаря библиотекам NodeJs.
Мы будем использовать библиотеку request-promise для получения HTML-страницы.
Результатом должен быть HTML-текст, отображаемый в консоли. Мы можем затем разобрать этот текст, чтобы собрать нужные данные и загрузить их.
Манипуляция страницей и получение данных
Я решил собрать данные с веб-сайта Al-maany, который использует арабские слова Корана для их перевода и показа корней каждого слова.
Первый шаг, который нам нужно сделать, - это понять структуру веб-страницы, используя инструменты разработчика Google Chrome, и определить, какие данные нам нужны. Затем мы напишем и настроим наш код для достижения этой цели.
С помощью инструмента разработчика я вижу, что данные, которые мне нужны, находятся в таблице со следующей структурой:
Таблица > Тело > строка > ячейка
Я также вижу, что некоторые теги td имеют дополнительные дочерние элементы, о которых я расскажу позже.
Теперь мы будем использовать cheerio, который является реализацией JQuery для серверной части NodeJS.
Я буду использовать тот же код, что и выше, но добавлю две строки, чтобы получить все теги td со страницы следующим образом:
const tds = $('table tbody tr td');
console.log(tds);
При запуске кода вы получите результат, который показывает все элементы td в указанной структуре на веб-странице, а также длину и тип элементов. Вы заметите, что каждый элемент имеет дочерние элементы в виде массива, и каждый дочерний элемент также имеет текстовые данные.
Теперь, когда у нас есть все элементы данных таблицы (td) с веб-страницы, нам нужно определить, какие данные нам нужно использовать для отображения и сбора с этой страницы.
Первые данные, которые мне нужны, - это само слово, которое находится во второй ячейке, поскольку первая ячейка указывает на стрелку для предыдущей веб-страницы. В то же время мне нужен корень, который находится в шестой ячейке на этой странице.
Мы можем получить их следующим образом:
const word = tds.eq(1).text();
const root = tds.eq(5).text();
Теперь у нас есть массив из двух элементов. Давайте протестируем его на другой странице с другими данными.
На этой странице у нас другое количество данных таблицы, что произошло из-за различного анализа слова, поэтому шестой элемент будет указывать на другие элементы.
Вы можете увидеть разницу между двумя страницами здесь.
В следующем фрагменте кода вы можете изменить ссылку URL, чтобы увидеть различие в длине между двумя страницами.
const url = 'https://almaany.com/quran/114/6/3/';
Чтобы решить эту проблему, я попытался найти другой подход и обнаружил закономерность: корень всегда является пятым элементом массива в обратном порядке. Поэтому мы можем немного изменить код и получить нужные данные следующим образом:
const word = tds.eq(1).text();
const root = tds.eq(-5).text();
Вы можете запустить код и увидеть результат из двух слов, которые показывают слово и его корень.
Таким образом, мы можем получить слово и его корень с веб-сайта, что является моей целью. Но я решил немного себя побаловать и получить токены и все из таблицы, а затем записать их в файл CSV, о чем я расскажу в другой части.
Для данных таблицы мы можем получить их, изменив количество дочерних элементов таблицы, поскольку у нас есть все они, и нам нужно только поместить их в массив. Что касается анализа, нам понадобится цикл для перебора всех анализов и сохранения их в тот же массив, затем мы можем получить ссылку на следующее слово и снова вызвать его для следующего вызова и получения его данных.