На сегодняшний день встречается очень много проектов, в которых необходимо собирать определённую информацию с чужих сайтов. Этот процесс называется "граббингом" или "парсингом". Оставим в стороне вопросы этичности этого процесса, предполагается, что вы знаете, что такое хорошо и что такое плохо, и не будете применять сие знание во вред кому-либо.
В этой статье мы создадим простой парсер на популярном языке PHP.
Заранее извиняюсь перед своими читателями, которые не знакомы с программированием, но специфика SEO зачастую предполагает наличие и программерских навыков. Итак, приступим.
Что будем парсить? В качестве учебного примера предлагаю создать средство для сбора статей широкоизвестного технического журналиста Криса Касперски (популярного автора журнала "Хакер").
Getting started
Статьи Криса расположены по этому адресу: http://www.xakep.ru/post/35410/default.asp. Это и будет нашей отправной точкой. Скачивание страницы для парсинга будем выполнять, используя библиотеку cURL. Итак, инициализируем библиотеку и скачиваем нашу страницу:
$ch = curl_init (); // инициализация curl_setopt ($ch , CURLOPT_URL , "http://www.xakep.ru/post/35410/default.asp"); curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0"); // каким браузером будем прикидываться curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); // вывод страницы в переменную $content = curl_exec($ch); // скачиваем страницу curl_close($ch); // закрываем соединение
Расчленение
В скачанной странице нас интересует ссылки на статьи и названия статей. Открываем код страницы в браузере и видим, что все ссылки и названия подчиняются следующему порядку расположения:
<p>Название статьи<br> <a href="адрес_статьи">адрес_статьи</a></p>
Напишем регулярное выражение, которое будет "выдирать" интересующие нас названия и адреса из кода страницы:
preg_match_all("/(.*)
(.*)\">.*<\/a><\/p>/isU", $content, $matches, PREG_PATTERN_ORDER);
\r\n\"
В рамки этой статьи не входит объяснение необъятной темы регулярных выражений, поэтому отсылаю вас к коротенькому справочнику по ним. Также рекомендую посмотреть информацию о функции preg_match_all для лучшего понимания кода.
Вырезка
Мы подошли к основному циклу программы. В нём мы будем скачивать странички со статьями и вырезать из них интересующую нас информацию.
Просматривая код страницы, можно обнаружить, что текст статьи всегда обрамлён следующими тегами
<hr width="200" size="1" noshade align="left"> ..текст статьи.. <center><p><a href="../">Содержание</a>
На основе этого закона мы и постоим парсер. Все необходимые поянения даны в комментариях:
for ($i = 0; $i < count($matches[1]); $i++) // цикл по всем извлеченным адресам { echo ""
.$matches[1][$i].""; // выводим название статьи как заголово flush(); // заставляем вывести текст немедленно $ch = curl_init (); // инициализация curl_setopt ($ch , CURLOPT_URL , $matches[2][$i]); // ссылка на текущую статью curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 "); curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); $content = curl_exec($ch); curl_close($ch); preg_match_all( "/
\"200\" size=\"1\" noshade align=\"left\">(.*)
Finish
Ну вот, собственно, и всё! В итоге мы получим ленту статей Криса, без рекламы, оформления сайта и прочих радостей.
Полный код скрипта:
$ch = curl_init (); curl_setopt ($ch , CURLOPT_URL , "http://www.xakep.ru/post/35410/default.asp"); curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0"); curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); $content = curl_exec($ch); curl_close($ch); preg_match_all("/(.*)
(.*)\">.*<\/a><\/p>/isU", $content, $matches, PREG_PATTERN_ORDER); for ($i = 0; $i < count($matches[1]); $i++) { echo "
\r\n\""
.$matches[1][$i].""; flush(); $ch = curl_init (); curl_setopt ($ch , CURLOPT_URL , $matches[2][$i]); curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0"); curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); $content = curl_exec($ch); curl_close($ch); preg_match_all( "/
\"200\" size=\"1\" noshade align=\"left\">(.*)
Если если вам понравилась эта статья, вы можете подписаться на материалы моего блога через
RSS
email
Twitter
ВКонтакте














эксперт
28 февраля 2010 г. ·

«You can't parse [X]HTML with regex. Because HTML can't be parsed by regex. Regex is not a tool that can be used to correctly parse HTML. As I have answered in HTML-and-regex questions here so many times before, the use of regex will not allow you to consume HTML. Regular expressions are a tool that is insufficiently sophisticated to understand the constructs employed by HTML. HTML is not a regular language and hence cannot be parsed by regular expressions. Regex queries are not equipped to break down HTML into its meaningful parts. so many times but it is not getting to me. Even enhanced irregular regular expressions as used by Perl are not up to the task of parsing HTML. You will never make me crack. HTML is a language of sufficient complexity that it cannot be parsed by regular expressions. Even Jon Skeet cannot parse HTML using regular expressions. Every time you attempt to parse HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your webapp…»
А еще вместо PHP нужно использовать Python. В котором есть, например, замечательный модуль xml.dom,minidom.
Zver, можно, но cURL — удобная штучка от которой грех отказываться.
Передаю через формы данные с одной страницы на другую:
URL:
далее, в index3.php (где ваш скрипт парсера сидит) хочу переменную urla вставить вместо урла сайта в эту строку Вашего скрипта:
curl_setopt ($ch , CURLOPT_URL , «http://www.xakep.ru/post/35410/default.asp»);
пробовал и так:
curl_setopt ($ch , CURLOPT_URL , $urla);
и так:
curl_setopt ($ch , CURLOPT_URL , $_POST['urla']);
но не получается заставить работать(
Может подскажете, где тут ошибка?
Заранее спасибо)
< form action=« index3.php» method=«post» >
URL:
< /form >
она туда доходит т.к.
echo $_POST['urla'];
работает нормально — выводит значение переменной
Искал и нашел.
Еще раз спасибо.
Т.е. я парсю огромный сайт, и что бы он не добавил мой айпи в блок, можно ли сделать так, что бы мой айпи адрес был не реальный, а вымышленный например, и все время разный.
Подскажите,
а как изменить код чтобы собирать информацию с сайта на котором требуемая информация появляется только после регистрации. Персональный код/пароль имеется.
Спасибо!
а то я уже неделю бьюсь
у большинства сайтов по кукам авторизация
подскажите начинающему где здесь ошибка я тупо поставил ваш скрипт какая ошибка?
(На кавычки внимания не обращайте,- пришлось изменить, чтобы отобразился код на этой странице)
Файл keys.txt — список кейвордов, где для гугла пробелы заменены на «+».
Когда я заменяю адрес с переменной $keyword
http://www.google.com/search?hl=en&num=$num&q=$keyword
на простой запрос, например слово keyword
http://www.google.com/search?hl=en&num=$num&q=keyword ,
то при парсинге в файл base.txt вписывается всё как надо. Цикл тоже запускается, но естественно запрос каждый раз повторяется один и тот же.
Когда же я в урле ставлю обратно переменную $keyword , парсится какая-то ерунда, совсем не по теме, хотя и с файла keys.txt при каждом новом цикле берется новый по порядку запрос. Может кто знает, что в коде не так. Не программер я, к сожелению.
Warning: curl_setopt(): supplied argument is not a valid cURL handle resource in C:\Program Files\VertrigoServ\www\parser\proxy\2ip.php on line 6
Буду благодарен за любую подсказку о природе проблемы.
http://mokro.info по своему ключу
photoprikol.netотличный пост, спасибо !
netwarez.net