Быстрое копирование информации с web-страницы (Парсинг)

Форум для тех кто начинает осваивать язык php.
lyod
Сообщения: 76
Поблагодарили: 1 раз

Быстрое копирование информации с web-страницы (Парсинг)

Сообщение lyod » Пн окт 20, 2014 10:27 pm

Здравствуйте.
Заметил, что на форумах часто задают вопросы про парсинг сайтов. Решил написать небольшую статью, в которой попытаюсь объяснить азы парсинга и привести некоторые примеры работы с ним.
Итак, начнём с самого начала.

Что такое парсинг? Это слово является переведенным, а вернее просто написанным на кириллице (как это часто встречается в интернете) словом из английского языка "parsing". Оно переводится с английского как "разбор". Т.е. парсинг - это анализ и разбор какой-либо web-страницы с целью получения информации, содержащейся на ней.

Можно подумать: а зачем вообще нужно получать информацию с web-страницы таким способом? Приведу пример: допустим, Вам нужна база данных MySQL с марками и моделями автомобилей (недавно как раз мне пришлось писать парсер именно для этого). Как Вам её получить? Есть два варианта. Первый - это купить такую базу у человека, у которого она есть. Второй - составить её самому.
Если Вас устраивает первый вариант - Вы, не тратя время, покупаете её и всё. Вот так просто :). Вспомнилась поговорка: счастье не в деньгах, а в больших деньгах :).

Но, допустим, Вы человек с пытливым умом и Вам интересно сделать что-то своими руками и Вы выбираете второй вариант.
Итак, Вы решили составить базу данных сами. Но откуда и как брать информацию? - Как откуда? - спросите Вы, можно найти какой-нибудь сайт, на котором есть списки марок и моделей автомобилей. Вы мыслите в правильном направлении, читатель. Итак, положим, Вы нашли сайт, на котором есть такие списки, создали у себя новую базу данных с двумя таблицами (одна для марок, другая для моделей автомобилей) и, довольные собой, начали копировать данные с сайта и вставлять в соответствующую таблицу.

...Прошло полчаса (тут щелчки старинных часов), Вы смотрите, сколько уже накопировали и, вот досада, обнаруживаете, что скопировали только сто марок (грубо говоря, мягко выражаясь), а ведь их около двухсот пятнадцати (на сайте авто.ру, будем считать, что Вы с него копируете :)). Ваше довольство собой как рукой сняло, внутри всё оборвалось (особенно если срочно нужна база).
Что делать, где пути, куда податься? Вы судорожно набираете в поисковике что-то типа "быстро получить информацию с web-страницы" и попадаете на этот замечательный форум и читаете данную статью.

А в данной статье находите решение - парсинг! Вы подпрыгиваете. Да, точно, мне нужен парсинг! А что это? Что это - я объяснил выше, а вот зачем он, объясняю сейчас. Он затем, чтобы БЫСТРО (буквально за 20-40 секунд) получить необходимые данные с web-страницы.
Программа для парсинга называется "парсер". Итак, парсер - это программа-"робот" (робот - потому что делает всё автоматически, без постоянного вмешательства человека), которая проходится по web-странице, и вытягивает нужные данные (нужные Вам, она вытягивает то, на что Вы её запрограммировали).

Использовать для разбора web-страницы регулярные выражения в чистом виде - не самый удачный выбор. Поэтому я Вам рекомендую использовать специальную библиотеку SimpleHTMLDom. Она составляет из HTML-документа дерево DOM, из которого потом и получает информацию. Что такое DOM, Вы можете узнать в википедии.

Если Вы работали ранее с jQuery, Вам будет просто понять принцип работы данный библиотеки (а кто не работал - ещё проще :)).
Скачайте себе библиотеку SimpleHTMLDom (с сайта http://simplehtmldom.sourceforge.net) и скопируйте в папку Вашего сайта. Затем подключите его в Вашем скрипте:

Код: Выделить всё

include('/путь к файлу/simple_html_dom.php');

Чтобы этой библиотеке было с чем работать (я про HTML-код), нужно "скормить" ей нужную Вам web-страницу. Делается это при помощи функции этой библиотеки file_get_html(). Ей нужно в виде аргумента передать ссылку на страницу, вот так:

Код: Выделить всё

$html = file_get_html( 'http://нужная Вам страница/' );

Теперь в переменной $html будет содержаться объект для работы с DOM web-страницы. Почему я упомянул jQuery? Потому, что в SimpleHTMLDom как и в jQuery обращаться к элементам страницы можно по классам, идентификаторам и тегам. К примеру, HTML-элементы, в которых содержатся нужные Вам название марок, имеют класс "mark". Чтобы получить объект для работы с этими элементами, Вы можете воспользоваться методом find(), аргументом которого является selector нужных Вам элемента. Значит сделать нужно так:

Код: Выделить всё

# Получаем все элементы с классом "mark"
$marks = $html->find('.mark');
  
# Обходим их в цикле и выводим название
foreach($marks as $mark)
      echo $mark->plaintext . PHP_EOL

Тут свойство "plaintext" возвращает весь текст (без HTML тегов), который содержится в элементе, который в данный момент обрабатывается циклом. Таким образом, Вы получили названия марок. Вы спросите,- а как я узнаю, какой selector у элемента, из которого мне нужно получить текст? Всё просто, Вам нужно тщательно просмотреть исходный код той страницы, с которой Вы планируете получить данные, найти нужный элемент, узнать его selector и затем передать его в аргументе методу.

Давайте попробуем написать парсер для получения марок автомобилей с сайта авто.ру. Открываем сайт и смотрим исходный код. Видим, что все марки находятся в HTML-тегах <a> с классом "marks-col-a". Отсюда следует, что именно этот selector мы должны передать в метод find().
Пишем код:

Код: Выделить всё

<?php
# Подключаем библиотеку для парсинга
require('simple_html_dom.php');
    
# Получаем объект для работы с DOM страницы
$html = file_get_html( 'http://auto.ru/' );
    
# Ищем в коде ссылки с классом marks-col-a
$marks = $html->find('.marks-col-a');
    
# Проходимся по найденным элементам
foreach($marks as $mark)
        # Выводим марку на экран
        echo $mark->plaintext . '<br>';
    
    
# Очищаем
    $html->clear();

Если попробовать его запустить - вы получите на экране список всех марок, какие есть на этом сайте. Как видно, я каждую марку вывожу с помощью echo. Это для наглядности, на самом деле, Вы, вместо вывода на экран, просто формируйте SQL-запрос и в конце скрипта запишите все марки в базу данных.
Также и с моделями. Как мы уже знаем, названия марок находятся в ссылках, значит URL ссылки можно получить так (в том цикле):

Код: Выделить всё

$mark->href;

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

Немного дополню. Функция file_get_html() получает данные с помощью file_get_contents(). Так как эта функция может работать не на всех хостингах, я рекомендую переписать эту функцию (у себя я переписал) под использование CURL.

Спасибо за внимание. Будут вопросы - пишите прямо сюда.
Реклама

Вернуться в «PHP»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость