Парсинг Веб-Страниц Для Веб-Разработчиков: Краткое Изложение

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

Понимание этого экономит время и помогает более эффективно решить проблему.



Парсинг веб-страниц для веб-разработчиков: краткое изложение

Многочисленные ресурсы рассказывают вам о единственно правильном методе извлечения данных с веб-страницы.

Но реальность такова, что для достижения этой цели можно использовать несколько решений и инструментов.

  • Какие существуют варианты программного извлечения данных с веб-страницы?
  • Плюсы и минусы каждого подхода?
  • Как использовать облачные ресурсы для повышения автоматизации?
Эта статья поможет вам получить ответы на эти вопросы.

Я думаю, ты уже знаешь, что это такое HTTP Запросы, ДОМ (Объектная модель документа), HTML , CSS-селекторы И Асинхронный JavaScript .

Если нет, советую углубиться в теорию, а затем вернуться к статье.



Статический контент

HTML-источники Начнем с самого простого подхода.

Если вы планируете парсить веб-страницы, это первое, с чего стоит начать.

Требует небольшой мощности компьютера и минимального времени.

Однако это работает только в том случае, если исходный код HTML содержит данные, на которые вы ориентируетесь.

Чтобы проверить это в Chrome, щелкните страницу правой кнопкой мыши и выберите «Просмотреть код страницы».

Теперь вы должны увидеть исходный код HTML. Как найдёте данные, напишите CSS-селектор , принадлежащий элементу-обертке, чтобы позже у вас была ссылка.

Чтобы реализовать это, вы можете отправить запрос HTTP GET на URL-адрес страницы и получить обратно исходный код HTML. В Узел вы можете использовать инструмент CheerioJS для анализа необработанного HTML и извлечения данных с помощью селектора.

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

  
  
  
   

const fetch = require('node-fetch'); const cheerio = require('cheerio'); const url = ' https://example.com/ '; const selector = '.

example'; fetch(url) .

then(res => res.text()) .

then(html => { const $ = cheerio.load(html); const data = $(selector); console.log(data.text()); });



Динамический контент

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

Типичным примером этого является SPA (одностраничное приложение), где HTML-документ содержит минимальное количество информации, а JavaScript заполняет его во время выполнения.

В этой ситуации решением является создание DOM и выполнение скриптов, находящихся в исходном коде HTML, так же, как это делает браузер.

Затем данные можно получить из этого объекта с помощью селекторов.

Безголовые браузеры Безголовый браузер — это то же самое, что и обычный браузер, только без пользовательского интерфейса.

Он работает в фоновом режиме, и вы можете управлять им программно, вместо того, чтобы щелкать и печатать.

Кукловод один из самых популярных headless-браузеров.

Это простая в использовании библиотека Node, предоставляющая высокоуровневый API для управления Chrome в автономном режиме.

Его можно настроить для запуска без заголовка, что очень удобно для разработки.

Следующий код делает то же самое, что и предыдущий, но он также будет работать с динамическими страницами:

const puppeteer = require('puppeteer'); async function getData(url, selector){ const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(url); const data = await page.evaluate(selector => { return document.querySelector(selector).

innerText; }, selector); await browser.close(); return data; } const url = ' https://example.com '; const selector = '.

example'; getData(url,selector) .

then(result => console.log(result));

Конечно, с Puppeteer можно делать и более интересные вещи, так что стоит посмотреть.

документация .

Вот фрагмент кода, который переходит по URL-адресу, делает снимок экрана и сохраняет его:

const puppeteer = require('puppeteer'); async function takeScreenshot(url,path){ const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(url); await page.screenshot({path: path}); await browser.close(); } const url = ' https://example.com '; const path = 'example.png'; takeScreenshot(url, path);

Для запуска браузера требуется гораздо больше вычислительной мощности, чем для отправки простого запроса GET и анализа ответа.

Поэтому выполнение происходит относительно медленно.

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

С другой стороны, этот метод очень гибок.

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

В общем, все, что можно сделать вручную в браузере.

Создание DOM Вы подумаете, что нет необходимости моделировать весь браузер только для создания DOM. Это действительно так, по крайней мере, при определенных обстоятельствах.

Джсдом — это библиотека Node, которая анализирует передаваемый HTML так же, как это делает браузер.

Однако это не браузер, а инструмент для создания DOM из заданного исходного кода HTML , а также для выполнения кода JavaScript в этом HTML. Благодаря этой абстракции Jsdom может работать быстрее, чем headless-браузер.

Если это быстрее, почему бы не использовать его вместо безголовых браузеров постоянно? Цитата из документации :

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

Это решение показано на примере.

Каждые 100 мс проверяет, появился ли элемент или истек срок его действия (через 2 секунды).

Он также часто выдает сообщения об ошибках, когда Jsdom не реализует на странице некоторые функции браузера, например: « Ошибка: не реализовано: window.alert…» или «Ошибка: не реализовано: window.scrollTo…» «Эту проблему также можно решить с помощью некоторых обходных путей ( виртуальные консоли ).

Обычно это API более низкого уровня, чем Puppeteer, поэтому вам придется реализовать некоторые вещи самостоятельно.

Это немного усложняет использование, как видно из примера.

Джсдом предлагает быстрое решение той же задачи.

Давайте рассмотрим тот же пример, но используя Джсдом :

const jsdom = require("jsdom"); const { JSDOM } = jsdom; async function getData(url,selector,timeout) { const virtualConsole = new jsdom.VirtualConsole(); virtualConsole.sendTo(console, { omitJSDOMErrors: true }); const dom = await JSDOM.fromURL(url, { runScripts: "dangerously", resources: "usable", virtualConsole }); const data = await new Promise((res,rej)=>{ const started = Date.now(); const timer = setInterval(() => { const element = dom.window.document.querySelector(selector) if (element) { res(element.textContent); clearInterval(timer); } else if(Date.now()-started > timeout){ rej("Timed out"); clearInterval(timer); } }, 100); }); dom.window.close(); return data; } const url = " https://example.com/ "; const selector = ".

example"; getData(url,selector,2000).

then(result => console.log(result));

Обратный инжиниринг Jsdom — это быстрое и простое решение, но вы можете сделать его еще проще.

Нужно ли нам моделировать DOM? Веб-страница, которую вы хотите парсить, состоит из тех же HTML и JavaScript, тех же технологий, которые вы уже знаете.

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

Чтобы упростить задачу, данные, которые вы ищете, могут быть:

  • часть исходного HTML-кода (как видно из первой части статьи),
  • часть статического файла, на который есть ссылка в документе HTML (например, строка в файле JavaScript),
  • ответ на сетевой запрос (например, некоторый код JavaScript отправил запрос AJAX на сервер, который ответил строкой JSON).

Доступ к этим источникам данных можно получить с помощью сетевых запросов.

.

Не имеет значения, использует ли веб-страница HTTP, WebSockets или какой-либо другой протокол связи, поскольку все они теоретически воспроизводимы.

Найдя ресурс, содержащий данные, вы можете отправить аналогичный сетевой запрос на тот же сервер, что и исходная страница.

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

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

Начните с мониторинга сетевого трафика.

Отличным инструментом для этого является вкладка Сеть в Chrome DevTools .

Вы увидите все исходящие запросы с ответами (включая статические файлы, запросы AJAX и т. д.), чтобы вы могли перебирать их и искать данные.

Если ответ будет изменен каким-либо кодом перед отображением на экране, процесс будет медленнее.

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

С другой стороны, он обеспечивает лучшую производительность.

На диаграмме показано необходимое время выполнения и размер пакета по сравнению с Jsdom и Puppeteer:

Парсинг веб-страниц для веб-разработчиков: краткое изложение

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



Интеграция облачных сервисов

Допустим, вы реализовали одно из перечисленных решений.

Один из способов запустить сценарий — включить компьютер, открыть терминал и запустить его вручную.

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

Это можно сделать, запустив реальный сервер и установив правила, определяющие время выполнения сценария.

В других случаях функция облака — более простой способ.

Облачные функции — это хранилища, предназначенные для выполнения загруженного кода при возникновении события.

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

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

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

Все зависит от вашей фантазии.

Популярные облачные провайдеры — Веб-сервисы Amazon (АВС) Облачная платформа Google (GCP) и Microsoft Azure :

Пользоваться этими услугами можно бесплатно, но недолго.

Если вы используете Puppeteer, облако Возможности Google - самое простое решение.

Размер пакета в формате Headless Chrome (~130 МБ) превышает максимальный размер архива, разрешенный в AWS Lambda (50 МБ).

Существует несколько способов заставить его работать с Lambda, но функции GCP по умолчанию поддержка Chrome без заголовка вам просто нужно включить Puppeteer в качестве зависимости в пакет.json .

Если вы хотите узнать больше о облачных функциях в целом, ознакомьтесь со статьей «Бессерверная архитектура».

По этой теме уже написано много хороших руководств, и у большинства поставщиков есть понятная документация.

Теги: #программирование #Программное обеспечение #JavaScript #Изучение языков #технологии #программирование #парсинг веб-страниц #Веб-разработка

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.