[Урок 3] . Получение любой информации со страницы при помощи Javascript
Каждый уважающий себя бот должен уметь извлекать любую информацию с сайта, например ссылки, заголовки, любой текст, номера телефонов, адреса электронной почты, картинки. В этом уроке мы рассмотрим несколько методов сбора данных на странице при помощи iMacros и Javascript.
Исходный код страницы
Для начала, я хочу очень кратко рассказать про то, из чего состоит веб-страница. Вы можете открыть любой сайт, например мой блог и нажать Ctrl+U (или правой кнопкой на странице и выбрать «Исходный код»). Вы увидите код, это обычный текст в формате HTML, который браузер преобразует в веб-страницу. Ключевые слова, заключенные в «<>» — называются тегами, свойства внутри них — атрибутами и значениями атрибута. Все это нам пригодится, чтобы отыскивать необходимые теги с нужной информацией.
Пример:
Что же делает браузер с этим кодом? Браузер, руководствуясь этим кодом, располагает информацию на странице в указанном порядке, подгружает таблицы стилей css, которые добавляют оформление элементам, подгружает и вставляет картинки, скачивает и выполняет различные скрипты. Правила, по которым браузер это делает — называются спецификацией, которая необходима, чтобы все браузеры отрисовывали страницы и обрабатывали скрипты одинаково.
DOM (Document Object Model) – объектная модель страницы
Основным инструментом работы и динамических изменений на странице является DOM (Document Object Model) – объектная модель, используемая для XML/HTML-документов. Согласно DOM-модели, документ является иерархией, деревом. Каждый HTML-тег образует узел дерева с типом «элемент». Вложенные в него теги становятся дочерними узлами. Для представления текста создаются узлы с типом «текст».
DOM – это представление страницы в виде дерева объектов, доступное для чтения и изменения через JavaScript.
При чтении неверного HTML браузер автоматически корректирует его для показа и при построении DOM. В частности, всегда будет верхний тег <html> . Даже если в тексте нет – в DOM он будет, браузер создаст его самостоятельно. То же самое касается и тега <body> . Например, если файл состоит из одного слова "Test" , то браузер автоматически обернёт его в <html> и <body> .
При генерации DOM браузер самостоятельно обрабатывает ошибки в документе, закрывает теги и делает все, чтобы корректно отобразить документ.
Методы извлечения информации из тегов средствами iMacros
У iMacros есть возможности для извлечения текста и даже html-кода из тегов. Для начала я рекомендую вам установить расширение FireBug, если вы этого еще не сделали. Открывается он по нажатию клавиши F12, либо вы можете нажать в любом месте страницы правой кнопкой и тыкнуть «Инспектировать элемент при помощи Firebug».
Чтобы потренироваться и как следует разобраться, я создал для вас специальную страничку http://polygon.nagibaka.ru/lessons/lesson3/index.htm
Давайте приступим, я рекомендую вам сразу открыть эту ссылку в Firefox. Поскольку вам предстоит писать много кода, рекомендую первым делом поставить себе какой-нибудь редактор, например весьма распространенный Notepad++ или же мой любимый и в сто раз более удобный Sublime Text 3, я писал о плагинах для него и режиме Vim для быстрого и мощного редактирования.
Давайте нажмем на «Запись» в iMacros, тыкнем по первому заголовку и остановим запись.
Мы получим вот такой скрипт(Current.iim):
Давайте переделаем его в JS. Создайте новый файл, например test.js. Допустим, нам необходимо получить содержимое тега "<H1>" . Переделаем макрос на js и извлечем из него содержимое тега "<H1>" .
Результат(test.js):
Обратите внимание — я заменил "Тестовая<SP>страница" на "*" — поскольку текст заголовка может быть любым, а звездочка нам говорит, что текст может быть произвольным TYPE=H1 — указывает что мы ищем тег « <H1> «, можно указать любой другой POS=1 — указывает, что мы выбираем первый попавшийся тег <H1> , ведь на странице их может оказаться несколько ATTR=TXT:* — указывает значение атрибута, в данном случае служебный атрибут, который ищет совпадение в тексте внутри тега EXTRACT=TXT — указывает, что мы извлекаем текст, также можно указать "EXTRACT=HTM" , чтобы извлечь текст вместе со всеми тегами
Методы извлечения информации из тегов средствами Javascript
Теперь давайте перепишем код полностью на JS без использования iim-команд. Еще, вместо iimDisplay мы будем использовать window.console.log('any text and vars'); Данные, которые мы будем выводить этой командой — будут отображаться в консоли firebug. Такой вариант удобнее по многим причинам, например, можно выводить js-объекты и удобно просматривать их содержимое. А самое главное, при помощи iimDisplay единовременно можно смотреть только последнее выведенное сообщение, а c этой командой мы увидим полный лог. Небольшое примечание, в некоторых старых версиях FF(например 27), window.console.log не всегда работало, и обратите внимание, нужно писать именно window.console.log , несмотря на то, что при создании обычных сайтов, чаще пишут просто console.log , весь наш код выполняется в контексте расширения iMacros, поэтому необходимо добавлять window .
Код на JS(test.js):
Здесь мы использовали поиск элемента по тегу. На самом деле, метод querySelector принимает в качестве параметра любое выражение в формате css-правила. Еще важно знать, что querySelector возвращает только первый элемент из DOM-дерева, который совпал. Чтобы получить все элементы, подходящие под указанное правило, используйте querySelectorAll .
Приведу несколько примеров:
Вы можете получать список всех элементов, подходящих под заданное правила, используйте для этого querySelectorAll() — он всегда возвращает коллекцию элементов либо null.
Давайте выведем все ссылки в консоль.
Тут мы видим набор элементов, а если быть точнее, то коллекцию узлов DOM-дерева. Квадратные скобки могут натолкнуть на мысль о том, что это обычный массив, но это не совсем так. Мы не сможем для такой коллекции использовать стандартные методы массива, такие, как .map(), .filter() и крайне удобный .forEach() . Поэтому для перебора и обработки элементов такой коллекции мы будем использовать классический цикл for .
В коллекции 6 элементов, вы можете нажать на любой и тогда откроется инспектор DOM-дерева и вы увидите элемент, на который нажали.
Хоть это и неполноценный массив, но нам все равно доступно свойство length . Давайте посчитаем количество ссылок в коллекции и выведем для каждой ссылки заголовок и адрес, куда она ссылается. В JS есть несколько вариантов реализации циклов, мы пока используем самый простой for .
Выводим все ссылки на странице и информацию о них:
Этот код покажет в консоли количество найденных элементов и выведет информацию о каждой ссылке на странице. Это базовый пример, позже вы научитесь создавать, изменять, фильтровать массивы полученной информации, сохранять в каком угодно виде и разумеется считывать из файлов и использовать данные в своих программах.
Помимо получения значений аттрибутов при помощи метода getAttribute() , текста внутри тега при помощи innerHTML, мы можем делать разные другие вещи. Чтобы посмотреть доступные методы, вы можете поискать в документации по JS, или воспользоваться автокомплитом из консоли, попробуйте вручную ввести window.document.querySelectorAll("a")[0]. или window.document.querySelector("a"). , что будет равнозначно, и после ввода точки появится список поддерживаемых методов и свойств, более подробно о каждом свойстве или методе вы легко найдете в гугле. Подобным образом вы сможете исследовать методы и свойства любого объекта. И еще, вы можете указывать несколько селекторов через запятую, например window.document.querySelectorAll("a, .styled")
Есть и другие методы для получения нужных нам тегов и извлечения из них различных свойств и атрибутов, но они не особо актуальны, потому что querySelectorAll — это метод, который поддерживают все современные браузеры, обладает куда большим функционалом и у нас нет необходимости использовать устаревшие методы, вроде window.document.getElementById() , window.document.getElementsByClassName() , window.document.getElementsByTagName() и прочие.
Также, для мощного поиска по тексту веб-страницы, можно использовать регулярные выражения, инструмент невиданной силы и мощи, который заслуживает отдельной книги страниц на 600, о нем я расскажу в следующих уроках.