Универсальный парсер контента php. Парсер на PHP – это просто


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

Способов сделать это существует уйма – например, имеется мощная программа, предназначение которой парсить сайты, называется content downloader . Среди минусов ее то, что она десктопная, то есть, работать с ней придется либо со своего компьютера, либо с удаленного сервера. Само собой программа платная, так что придется еще и заплатить какую-то сумму денег, чтобы использовать ее (имеется несколько типов лицензий).

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

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

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

Что для этого требуется? Основные знания php, то есть умение работать с данными, хорошее владение синтаксисом, и опыт работы с библиотекой cURL .

Как же выдрать нужные данные со страницы? Сначала обязательно следует скачать саму страницу, например, с помощью библиотеки cURL, хотя можно воспользоваться и стандартной функцией file_get_contents, если хостинг поддерживает удаленное подключение через fopen. cURL к слову очень мощный инструмент для составления POST, GET запросов, использования прокси и вообще всего, чего только душе угодно, плюс установлен на любом хостинге практически.

Теперь данные нужно обработать, тут следует выбрать, каким образом выдирать информацию со страницы. Можно воспользоваться стандартными функциями php, вроде strpos, substr и т.д., но это настолько криво, что лучше об этом даже не думать.

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

Благо, что существуют уже готовые библиотеки, которые позволяют сосредоточиться непосредственно на работе со страницей, как с DOM (Document Object Model).

$doc = new DOMDocument(); $doc->loadHTML ($data);

Первая строчка создает объект, а вторая создает из обычных string данных (в которых должно находиться содержимое страницы) создает DOM.

$searchNodes = $doc->getElementsByTagName("a");

Теперь в переменной $searchNodes находится массив из найденных тегов "a".

Foreach ($searchNodes as $cur) { echo $cur->getAttribute("href"); }

А этот код выведет все значения полей href (обычно это адрес, куда попадает пользователь после нажатия на ссылку).

Более подробно с данной мощной библиотекой можно ознакомиться в официальной документации.

Но если вы хотите еще проще и удобней, то обратите внимание на библиотеку PHP Simple HTML DOM Parser. Она очень удобна и проста в освоении, разобраться, что к чему можно буквально за 10-15 минут, однако, с некоторыми типами данных она работает не слишком хорошо.

Существуют еще библиотеки, но эти две наиболее удобны и просты в освоении.


10
Сен

Как написать парсер для сайта

Недавно мне была поставлена задача написать php парсер сайта. Поставленная задача была выполнена и благодаря ей появилась эта заметка. До этого я ничего подобного не делал, так что не судите строго. Это мой первый парсер php.

И так с чего начать решение вопроса "как написать парсер". Давайте для начала разберёмся что это такое. В простонародье парсер(parser) или синтаксический анализатор - это программа которая получает данные (например веб страница), как то их анализирует структурирует, делает выборку и потом проводит какие то операции с ними (пишем данные в файл, в БД или выводим на экран). Данную задачу нам нужно выполнить в рамках веб программирования.

Для заметки я придумал такую тестовую задачу. Нужно спарсить по определённому поисковому запросу ссылки на сайты с 5 первых страниц выдачи и вывести их на экран. Парсить я решил выдачу поисковой системы bing. А почему бы не написать парсер яндекса или гугла спросите вы. Такие матёрые поисковики имеют не хилую защиту от парсинго(капча, бан ip, меняющаяся разметка, куки и тд), и это тема отдельной статьи. В этом плане с бингом таких проблемм нет. И так что нам нужно будет сделать:

  • Получить (спарсить) контент html страницы средствами php
  • Получить интересующие нас данные(а конкретно ссылки)
  • Спарсить постраничную навигацию и получить ссылку на следующую страницу
  • Опять спарсить страницу по ссылке, получить данные, получить следующую ссылку
  • Проделать выше описанную операцию N количество раз
  • Вывести все полученные ссылки на экран
Получение и парсинг страницы

Сначала напишем функцию, потом её разберём

Function getBingLink($link){ $url="https://www.bing.com/search"; //получаем контент сайта $content= file_get_contents($url.$link); //убираем вывод ошибок libxml_use_internal_errors(true); //получаем объект класса DOMDocument $mydom = new DOMDocument(); //задаём настройки $mydom->preserveWhiteSpace = false; $mydom->resolveExternals = false; $mydom->validateOnParse = false; //разбираем HTML $mydom->loadHTML($content); //получаем объект класса DOMXpath $xpath = new DOMXpath($mydom); //делаем выборку с помощью xpath $items=$xpath->query("//*[@class="b_algo"]/h2/a"); //выводим в цикле полученные ссылк static $a=1; foreach ($items as $item){ $link=$item->
"; $a++; } }

И так разберём функцию. Для получения контента сайта используем php функцию file_get_contents($url.$link) . В неё подставляем адрес запроса. Есть ещё много методов получения контента html страницы, например cUrl, но на мой взгляд file_get_contents самый простой. Потом вызываем объект DOMDocument и так далее. Это всё стандартно и об этом можно почитать в интернете поподробнее. Хочу заакцентировать внимание на методе выборки нужных нам элементов. Для этой цели я использую xpath. Мою xpath шпаргалку можно глянуть . Есть и другие методы выборки такие как регулярные выражения, Simple HTML DOM, phpQuery. Но на мой взгляд лучше разобраться с xpath, это даст дополнительные возможности при работе с xml документами, синтаксис полегче чем с регулярными выражениями, в отличии от css селекторов можно найти элемент по находящемуся в нём тексту. Для примера прокомментирую выражение //*[@class="b_algo"]/h2/a . Подробнее синтаксис можно посмотреть в моей шпаргалке xpath. Мы выбираем со всей страницы ссылки лежащие в теге h2 в диве с классом b_algo . Сделав выборку мы получим массив и которого в цикле выведем на экран все полученные ссылки.

Парсинг постраничной навигации и получение ссылки на следующую страницу

Напишем новую функцию и по традиции разберём её позже

Function getNextLink($link){ $url="https://www.bing.com/search"; $content= file_get_contents($url.$link); libxml_use_internal_errors(true); $mydom = new DOMDocument(); $mydom->preserveWhiteSpace = false; $mydom->resolveExternals = false; $mydom->validateOnParse = false; $mydom->loadHTML($content); $xpath = new DOMXpath($mydom); $page = $xpath->query("//*[@class="sb_pagS"]/../following::li/a"); foreach ($page as $p){ $nextlink=$p->getAttribute("href"); } return $nextlink; }

Почти идентичная функция, изменился только xpath запрос. //*[@class="sb_pagS"]/../following::li/a получаем элемент с классом sb_pagS (это класс активной кнопки постраничной навигации), поднимаемся на элемент вверх по dom дереву, получаем первый соседний элемент li и получаем в нём ссылку. Эта и есть ссылка на следующую страницу.

Парсим выдачу N количество раз

Пишем функцию

Function getFullList($link){ static $j=1; getBingLink($link); $nlink=getNextLink($link); if($j

Данная функция вызывает getBingLink($link) и getNextLink($link) пока не кончится счётчик j. Функция рекурсивная, то есть вызывает сама себя. Про рекурсию почитайте подробнее в интернете. Обратите внимание что $j статическая, то есть она не удаляется при следующем вызове функции. Если бы это было не так, то рекурсия бы была бесконечной. Ещё добавлю из опыта, если хотите пройти всю постраничную навигацию то пишите if условие пока есть переменная $nlink. Есть ещё пара подводных камней. Если парсер работает долго то это может вызвать ошибку из за времени выполнения скрипта. По умолчанию 30с. Для увеличения времени в начале файла ставте ini_set("max_execution_time", "480"); и задавайте нужное значение. Так же может возникать ошибка из за большого количества вызовов одной функции (более 100 раз). Фиксится отключением ошибки, ставим в начало скрипта ini_set("xdebug.max_nesting_level", 0);

Теперь нам осталось написать html форму для ввода запроса и собрать парсер воедино. Смотрите листинг ниже.







2024 © gtavrl.ru.