Парсер, паук, бот, робот или все равно как вы его назовете — это программа, которая автоматически получает (парсит) и обрабатывает данные с сайтов.
Например, Google индексирует и ранжирует страницы с помощью многочисленных пауков и ботов. Кроме того, есть проверяльщики ссылок, HTML валидаторы и веб-шпионы. Да, в этой статье мы вам покажем, как сделать своего веб-шпиона на PHP.
Зачем вам это? Вам может быть и не понадобится, а покупателю или заказчику, имеющему много конкурентов, очень даже. С помощью такого паука очень удобно отслеживать цены в автоматическом режиме.
1 – Требования
- PHP сервер – также нужен cron.
- MySQL – будем хранить данные в ней.
2 – Основы
Начнем с основного функционала, и для этого попытаемся получить немного данных от источника. Предположим, что вы продаете обувь, и Zappos ваш основной конкурент (об этом можно только мечтать).
Например, возьмем NIKE FREE RUN+ 2. Сначала будем использовать fopen, чтобы открыть страницу, далее fgets, чтобы ее прочитать и feof для проверки, когда нужно закончить читать. Сейчас нужно проверить, чтобы функция fopen была доступна на сервере (можно проверить через phpinfo ). Первые строки кода:
1 2 3 4 5 6 7 8 9 10 11 |
<?php if(!$fp = fopen("http://www.zappos.com/nike-free-run-black-victory-green-anthracite-white?zlfid=111" ,"r" )) { return false; } //если fopen сработал $content = ""; while(!feof($fp)) { // $content .= fgets($fp, 1024); } fclose($fp); //закрываем ?> |
Если вы отобразите контент из переменной $content
на экран, то увидите HTML код без вставок CSS или JS. Это особенность подключения таких файлов на zappos.
У нас есть контент, теперь нужна цена товара.
Как отличить цену от любой другой цифры на странице? Очевидно, что перед ценой стоит знак доллара “$”. Чтобы найти цифру с этим знаком, мы будем использовать регулярные выражения.
Но в этом случае регулярное выражение будет срабатывать на любой цене на странице. И здесь Zappos пошел на встречу шпионам (и не только им). Официальная цена продукта идет всегда первой. Остальные цены идут дальше, таким образом, мы можем их игнорировать.
Код будет выглядеть так:
1 2 3 4 5 6 7 |
<?php //здесь fopen, fgets //здесь regex preg_match_all("/([$][0-9]*[,]*[.][0-9]{2})/", $content, $prices, PREG_SET_ORDER); echo $prices[0][0]."<br />"; ?> |
Цена у нас есть.
3 – Сохранение данных в MySQL
Подготовим базу данных. Создадим таблицу с именем zappos. Она будет состоять из четырех столбцов:
- ID — Первичный ключ таблицы
- Date — Когда были сохранены данные, что хорошо для отчетов.
- Value — Найденное значение
- Other_Values — Не нужные нам значения. На всякий случай, если владелец сайта поменяет html структуру страницы
В phpmyadmin создаем базу с именем spy, и вставляем в нее таблицу zappos:
1 2 3 4 5 6 7 |
CREATE TABLE IF NOT EXISTS `zappos` ( `ID` int(5) NOT NULL AUTO_INCREMENT, `Date` date NOT NULL, `Value` float NOT NULL, `Other_Values` char(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; |
Таблицу создали, теперь можно добавлять в нее данные. Для этого нужно mysql подключение в PHP и подготовленные цены для сохранения.
Подготовка цен заключается в том, чтобы удалить из данных все пробелы, запятые и точки.
Для соединения с базой мы будем использовать mysql_connect
, далее mysql_select_db
, чтобы выбрать базу “spy” и mysql_query
, чтобы сохранить данные.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<?php //подготовка данных $otherValues = ""; foreach ($prices as $price) { $otherValues .= str_replace( array("$", ",", " "), '', $price[0]); // $otherValues .= ","; //разделяем значения запятой } //если Zappos изменит структуру данных (или вы смените сайт), то вносить правки здесь $mainPrice = str_replace( array("$", ",", " "), '', $prices[0][0]); //дата в формате YYYY-MM-DD $date = date('Y\-m\-d'); $dbhost = 'localhost'; $dbuser = 'root'; $dbpass = ''; $dbname = "spy"; $dbtable = "zappos"; $conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql'); echo "<br />Connected to MySQL<br />"; $selected = mysql_select_db($dbname) or die( mysql_error() ); echo "Connected to Database<br />"; //сохранение данных $insert = mysql_query(" INSERT INTO `$dbname`.`$dbtable` ( `ID` , `Date` , `Value` , `Other_values` ) VALUES ( NULL , '$date', '$mainPrice', '$otherValues' ); "); //получение данных $results = mysql_query("SELECT * FROM $dbtable"); mysql_close($conn); // while($row = mysql_fetch_array($results, MYSQL_ASSOC)) { echo "ID :{$row['ID']} " . "Date : {$row['Date']} " . "Value : {$row['Value']}"; echo "<br />"; } ?> |
4 – Умный шпион с помощью cron
С помощью cron, мы можем автоматизировать выполнение заданий. Очень полезно для сохранения бэкапов баз данных, оптимизации и многих других рутинных штук, которые не хочется делать вручную.
Чтобы наполнять нашу таблицу данными, нам нужно создать задание для cron, которое будет исполняться каждый день в 1 час ночи.
У нас есть команды, необходимые для этого:
Посмотреть файл cron
5 – Немного симпатичных диаграмм
Если вы планируете использовать эти данные, то неплохо бы их как-то оформить.
В этом случае можно подключить gvChart jQuery плагин. Он берет данные из таблиц, оформленные через массив, и выводит их в виде симпатичных диаграмм.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php $dbhost = 'localhost'; $dbuser = 'root'; $dbpass = ''; $dbname = "spy"; $dbtable = "zappos"; $conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql'); $selected = mysql_select_db($dbname) or die( mysql_error() ); //get data $results = mysql_query("SELECT * FROM $dbtable ORDER BY `ID` DESC LIMIT 15"); mysql_close($conn); $dates = array(); $values = array(); while($row = mysql_fetch_array($results, MYSQL_ASSOC)) { $dates[] = "{$row['Date']}"; $values[] = "{$row['Value']}"; } echo "<table id='real'>"; echo "<caption>Real Prices on Zappos.com</caption>"; echo "<thead>"; echo "<tr>"; echo "<th></th>"; foreach($dates as $date) { $date = explode('-', $date); echo "<th>" . $date[2] . "</th>"; } echo "</tr>"; echo "</thead>"; echo "<tbody>"; echo "<tr>"; echo "<th>" . $date[0] . "-" . $date[1] . "</th>"; foreach($values as $value) { echo "<td>" . $value . "</td>"; } echo "</tr>"; echo "</tbody>"; ?> |
Улучшения?
Этого паука-парсера можно развивать до бесконечности. Например, сделать лист ожидания, где будут списки товаров с разных сайтов и т.д. и т.п.
А какие улучшения сделали бы вы?
P.S.: Интересуют услуги по созданию сайтов? Обращайтесь в компанию
Kraftwork, они уже давно занимаются разработкой сайтов в Москве и делают это неплохо.
А если есть необходимость предворительного входа через логин и пароль? Допустим мне известен логин и пароль, но информация находится внутри аккаунта. Если я залогинюсь, а потом использую скрипт чтения страницы, то не особо получается... Считывается главная страница, какбуд-то вход не производился.
здесь больше curl поможет.
недавно о нем речь шла, почитайте.
Прошу помощи, в объяснении.
Спайдер, этот, получает контент страницы БЕЗ html,в то время как
Crawler должен брать ссылки, если брать их из базы спайдера, то придётся опять брать контент , но С html.
Пожалуйста , объясните мне , как взаимодействовать должны спайдер и краулер.
Сюда, пожалуйста , кому не трудно : noizefan1@mail.ru
Вы запутались немного.
В статье шла речь о конкретном функционале — получение цены по определенному товару.
Спайдер и краулер — это одно и то же.
Возможно я и запутался)
А как называется переходчик по ссылкам?
--Crawler.
Выделяет все ссылки, присутствующие на странице. Его задача — определить, куда дальше должен идти паук, основываясь на ссылках или исходя из заранее заданного списка адресов. Краулер, следуя по найденным ссылкам, осуществляет поиск новых документов, еще неизвестных поисковой системе.— из глубины интернета.
Теперь понятно, о чем вы хотели сказать.
В данной статье идет речь только о пауке, если вам нужен материал по построению простейшей поисковой системы, то я постараюсь найти и опубликовать в ближайшее время перевод простейшей ПС.
Спасибо огромное.
Кстати я добавил в конце статьи код создания простейшего робота-паука с помощью PHP