Парсинг выдачи Google. Практика.
Очень часто перед веб-мастерам встает задача парсинга выдачи поисковиков.
Это может быть нужно для того, чтобы:
- автоматизировать процесс обработки какой-то статистической информации;
- посчитать количество ссылающихся на ваш сайт ресурсов, определить их качество и прочие параметры;
- найти урлы сайтов, которые натырили у вас контент (хотя тут лучше использовать что-то наподобии CopyScape, однако я заметил, что он иногда выдает бред);
- определить частоту запросов.
И это лишь малый диапазон задач, в которых вам может понадобиться парсинг выдачи поисковиков. А точнее это то, что мне пришло в голову
А ведь еще у нас есть такие ребята как серые и черные оптимизаторы, которые при помощи поисковика ищут спамилки. Но это вообще отдельный разговор, который ничего общего с нашими благими целями не имеет
В данной статье я хотел бы рассказать как проще всего из выдачи Google доставать такие параметры как:
- время генерации ответа (может понадобиться для статистики и расчета общего времени парсинга);
- количество страниц, соответствующих вашему запросу (частота);
- ну и собственно ссылки на конечные ресурсы.
Реализовывать механизм получения выдачи вы можете на чем угодно: curl, сокеты, fopen. Особой разницы для нас между ними нет. Предположим, что получать содержимое выдачи вы уже умеете (а если не умеете, то читать дальше вам просто незачем).
И вот тут начинаются вопросы.
1. Как достать из выдачи время генерации и количество страниц на данный запрос?
Я делаю это таким кодом (выдрано из тучи моих классов и гигантского ядра парсера, так что если найдете какую-то ошибку - напишите в комментах):
$blue_line_pcre = "(Результаты|Результати|Results)(.*)"; $parse_time_pcre= '\<b\>([\d\,\.]+)\<\/b\>\s[^\d]+$'; $parse_num_pcre = '\<b\>([\d\,]+)\<\/b\>[^\d]+'; if(preg_match("/$blue_line_pcre/Ui",$Result,$matches)) { unset($matches[0]); if(!empty($matches[1])) { $BlueLine=preg_replace("/\ \;/",'',$matches[2]); } else { $BlueLine=''; } } $find=$parse_num_pcre.$parse_time_pcre; if(preg_match("/$find/Ui",$BlueLine,$matches)) { unset($matches[0]); $query_results_num=$matches[1]; $query_time=$matches[2]; }
То есть, предполагается, что в переменной $Result хранится html код выдачи (и очено важно к этому коду не забыть применить
$Result=preg_replace("/[\n\r\t]/", '', $Result);
, чтобы потом не ломать голову почему половина регулярок не работают).
После выполнения моего скрипта в переменной $BlueLine будет html код синей полоски Гугла, в которой будет написано, что-то на подобии “Результаты 1 - 10 из примерно 87 300 000 для вакансии. (0,04 секунд)”.
В переменной query_results_num будет количество сайтов, подходящих под ваш запрос, а в переменной query_time - время генерации выдачи.
Из кода выше вы могли заметить, что регулярное выражение для нахождения кода “синей линии” имеет следующий непонятный вид:
(Результаты|Результати|Results)(.*)
Это сделано исключительно для того, чтобы с равной точностью парсить выдачу как google.com, так и google.ru и google.com.ua.
Заметка: результаты выдачи по одному и тому же запросу на разных локализованных версиях Google отличаются! Хоть иногда эту разницу тяжело обнаружить, но все же она есть. Можете на досуге поиграться с каким-то ВЧ запросом. Расскажете о результатах своих наблюдений.
Также некоторые вопросы могут вызывать регулярные выражения для нахождения времени генерации и количества страниц:
$parse_time_pcre = '\<b\>([\d\,\.]+)\<\/b\>\s[^\d]+$'; $parse_num_pcre = '\<b\>([\d\,]+)\<\/b\>[^\d]+';
Для чего я использую вот такие конструкции [\d\,\.]? Исключительно для совместимости. Делаю я это потому, что разделителем целой и дробной части в нашей стране является “.”, а в США - “,”. В регулярном выражении для количества страниц вы также можете видеть символ “\,” - это используется для того, чтобы правильно находить количество страниц, так как американцы разделяют тысячи этим знаком.
2. Как достать ссылки из выдачи?
Эта даже проще чем выдирать параметры. Я делаю это при помощи следующего кода:
$find = $parse_links_pcre = "<a\shref=\"([^\"]+)\".*sclass=l"; if(preg_match_all("/$find/Ui",$Result,$matches)) { unset($matches[0]); $links=$matches[1]; }
В массиве $links будут все ссылки, найденный на текущей странице. Недостатки у такой унификации тоже есть: в результирующем массиве вы получите все ссылки “Translate” и этот метод не очень-то и быстро работает из-за использования в регулярном выражении “.*”. Но это место всегда можно подрихтовать под ваши конкретные требования. В оригинальном виде я тоже не особо часто использую данное регулярное выражение. Но есть также и плюсы у этого кода: он не загребает ссылки с оплаченных объявлений, а они, как вы знаете, вылазят на каждой странице поиска и могут очень сильно нарушить ваши статистические исследования или сбор ссылок.
Спасибо, что дочитали до конца. Рад буду выслушать ваши предложения и дополнения.

ParserPro » Архивы сайта » Выдача Google:
[…] Контакты « Парсинг выдачи Google. Практика. […]
11 Октябрь 2007, 5:26 ппMendel:
будь проще и к тебе потянутся люди

как взять контент это какраз один из сложнейших этапов… брать то надо красиво
простейший пример с прокси и максимальной скоростью работы:
а по теме, так мудрено слишком…
проще например так:
фсё….можно проще конечно, но лень
13 Октябрь 2007, 1:14 дпadmin:
Ну я и так старался не очень мудрить
Сори, если уж слишком закрутил.
Я код “синей линии” достаю отдельно только потому что он иногда может понадобиться для анализа.
А вот по поводу вашего кода могу сказать, что вот это:
не найдет на google.com нужного нам числа. А в трудовых буднях работника парсинга приходится и его выдачу “анализировать”.
Я же в свою очередь пытался сделать универсальный инструмент. Может и не получилось. Но я буду стараться
13 Октябрь 2007, 8:52 дпMendel:
исправил на google.com - parse.com.ua - скрипт выдал 10 страниц…

ну да ладно, если тебе нужно…
13 Октябрь 2007, 4:54 ппне забывай что мы уже удалили
зачем тащить всю синюю линию в упор не понимаю - 1-10 неинформативно, что я запрашивал я и так знаю, а сколько времени у гоши ушло так это ему надо считать а не мне
Mendel:
блин, во второй строчке жесткий пробел был схаван. обведи его [html] плиз…
13 Октябрь 2007, 4:55 ппadmin:
Этот вордпресс меня уже порядком поднапряг
Хавает коды как хочет
Но ваша регулярка все равно не универсальная получилась и даже очень не универсальная!
Она вытащит только числа до 999 включительно, потому что потом google.com будет отдавать страницы в виде “1,000″, что уже не подходит под ваш шаблон регулярного выражения.
Можете проверить на каком-то ВЧ запросе, а не на “parse.com.ua”
13 Октябрь 2007, 8:27 ппMendel:
http://www.google.com/search?q=site:domenforum.net

13 Октябрь 2007, 11:03 ппкак и com.ua отдает с пробелами, которые уже удалены
но если у вас такой запрос что гоша почемуто отдает с запятой то либо добавте после девятки запятую либо в прелидущей щамене замените пробел на запятую… ладно, не будем спорить о стиле. в ваших задачах удобнее ваш код, в моих быстреее мой
admin:
Ок.
14 Октябрь 2007, 2:54 ппНо и по той ссылке, что вы дали он мне отдал число с запятой
hamster:
О, классно. Очень полезно. Искал что-то подобное, но не думал, что найду тут.. Сам пока осваиваю программинг - еще зеленый.)
11 Ноябрь 2007, 3:04 ппadmin:
Всегда рад помочь!
11 Ноябрь 2007, 3:25 пп[YS.PRO]:
$Result=preg_replace(”/[\n\r\t]/”, ”, $Result);
Ох не нравится мне это, зачем комп мучать?
30 Ноябрь 2007, 12:26 дп$result = str_replace(array(”\n”, “\r”, “\t”), ”, $result);
admin:
Я не знаю, но как я наблюдал так нагрузка не такая уж и громадная :)))
1 Декабрь 2007, 9:08 ппНу по крайней мере мой двухядерный Атлон с легкостью справляется :))))))
ParserPro » Архивы сайта » Тест. Кто быстрее: preg_replace() или str_replace()?:
[…] к моему посту “Парсинг выдачи Google. Практика.” [YS.PRO] оставил коммент следующего содержания: […]
1 Декабрь 2007, 10:31 ппВиктор:
Спасибо было полезно, узнал много нового
5 Май 2008, 3:31 пп