Парсинг всех ссылок с любого сайта

psics
На сайте с 02.04.2009
Offline
130
7322

Привет всем.

Мне нужно спарсить все внутренние ссылки с любого сайта. Нашел вот такой код

    // Поможет при длительном выполнении скрипта
set_time_limit(0);
$host='----.com'; // Хост сайта
$scheme='http://'; // http или https?
$urls=array(); // Здесь будут храниться собранные ссылки
$content=NULL; // Рабочая переменная
// Здесь ссылки, которые не должны попасть в sitemap.xml
$nofollow=array('/out/','/error/');
// Первой ссылкой будет главная страница сайта, ставим ей 0, т.к. она ещё не проверена
$urls[$scheme.$host]='0';
// Разрешённые расширения файлов, чтобы не вносить в карту сайта ссылки на медиа файлы. Также разрешены страницы без разрешения, у меня таких страниц подавляющее большинство.
$extensions[]='php';$extensions[]='aspx';$extensions[]='htm';$extensions[]='html';$extensions[]='asp';$extensions[]='cgi';$extensions[]='pl';
// Корневая директория сайта, значение можно взять из $_SERVER['DOCUMENT_ROOT'].'/';
$engine_root='/home/----/public_html/----.com/';

// Функция для сбора ссылок
function sitemap_geturls($page,&$host,&$scheme,&$nofollow,&$extensions,&$urls)
{
//Возможно уже проверяли эту страницу
if($urls[$page]==1){continue;}
//Получаем содержимое ссылки. если недоступна, то заканчиваем работу функции и удаляем эту страницу из списка
$content=file_get_contents($page);if(!$content){unset($urls[$page]);return false;}
//Отмечаем ссылку как проверенную (мы на ней побывали)
$urls[$page]=1;
//Проверяем не стоит ли запрещающий индексировать ссылки на этой странице мета-тег с nofollow|noindex|none
if(preg_match('/<[Mm][Ee][Tt][Aa].*[Nn][Aa][Mm][Ee]=.?("|\'|).*[Rr][Oo][Bb][Oo][Tt][Ss].*?("|\'|).*?[Cc][Oo][Nn][Tt][Ee][Nn][Tt]=.*?("|\'|).*([Nn][Oo][Ff][Oo][Ll][Ll][Oo][Ww]|[Nn][Oo][Ii][Nn][Dd][Ee][Xx]|[Nn][Oo][Nn][Ee]).*?("|\'|).*>/',$content)){$content=NULL;}
//Собираем все ссылки со страницы во временный массив, с помощью регулярного выражения.
preg_match_all("/<[Aa][\s]{1}[^>]*[Hh][Rr][Ee][Ff][^=]*=[ '\"\s]*([^ \"'>\s#]+)[^>]*>/",$content,$tmp);$content=NULL;
//Добавляем в массив links все ссылки не имеющие аттрибут nofollow
foreach($tmp[0] as $k => $v){if(!preg_match('/<.*[Rr][Ee][Ll]=.?("|\'|).*[Nn][Oo][Ff][Oo][Ll][Ll][Oo][Ww].*?("|\'|).*/',$v)){$links[$k]=$tmp[1][$k];}}
unset($tmp);
//Обрабатываем полученные ссылки, отбрасываем "плохие", а потом и с них собираем...
for ($i = 0; $i < count($links); $i++)
{
//Если слишком много ссылок в массиве, то пора прекращать нашу деятельность (читай спецификацию)
if(count($urls)>49900){return false;}
//Если не установлена схема и хост ссылки, то подставляем наш хост
if(!strstr($links[$i],$scheme.$host)){$links[$i]=$scheme.$host.$links[$i];}
//Убираем якори у ссылок
$links[$i]=preg_replace("/#.*/X", "",$links[$i]);
//Узнаём информацию о ссылке
$urlinfo=@parse_url($links[$i]);if(!isset($urlinfo['path'])){$urlinfo['path']=NULL;}
//Если хост совсем не наш, ссылка на главную, на почту или мы её уже обрабатывали - то заканчиваем работу с этой ссылкой
if((isset($urlinfo['host']) AND $urlinfo['host']!=$host) OR $urlinfo['path']=='/' OR isset($urls[$links[$i]]) OR strstr($links[$i],'@')){continue;}
//Если ссылка в нашем запрещающем списке, то также прекращаем с ней работать
$nofoll=0;if($nofollow!=NULL){foreach($nofollow as $of){if(strstr($links[$i],$of)){$nofoll=1;break;}}}if($nofoll==1){continue;}
//Если задано расширение ссылки и оно не разрешёно, то ссылка не проходит
$ext=end(explode('.',$urlinfo['path']));
$noext=0;if($ext!='' AND strstr($urlinfo['path'],'.') AND count($extensions)!=0){$noext=1;foreach($extensions as $of){if($ext==$of){$noext=0;continue;}}}if($noext==1){continue;}
//Заносим ссылку в массив и отмечаем непроверенной (с неё мы ещё не забирали другие ссылки)
$urls[$links[$i]]=0;
//Проверяем ссылки с этой страницы
sitemap_geturls($links[$i],$host,$scheme,$nofollow,$extensions,$urls);
}
return true;
}

// (START!) Первоначальный старт функции для проверки главной страницы и последующих
sitemap_geturls($scheme.$host,$host,$scheme,$nofollow,$extensions,$urls);



// Добавляем каждую ссылку
foreach($urls as $k => $v){echo $k.'<br />';}




Но что не нравится / не подходит.

Какая то проблема со страницами при задании одновременно относительных и абсолютных путей.

А так вроде норм работает...

pigalica
На сайте с 16.06.2010
Offline
40
#1

Я когда писал парсеры на php чаще всего пользовался библиотекой PHP Simple HTML DOM Parser

тогда с кодом получится всё намного проще и понятнее:


// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');

foreach($html->find('a') as $element) //Находим все линки
echo $element->href . '<br>'; //выводим их на экран

Библиотека в этом плане намного проще чем свой код. Проверено работает, много примеров, хорошая документация PHP Simple HTML DOM Parser Manual

Capitalist - все платежные системы под одной крышей (https://capitalist.net/reg?from=c7a0f297a0)
psics
На сайте с 02.04.2009
Offline
130
#2

спасибо на выходных попробую. А подключение - скачать файлы и инклудить их?

pigalica
На сайте с 16.06.2010
Offline
40
#3
psics:
спасибо на выходных попробую. А подключение - скачать файлы и инклудить их?

Да, там всё просто. Там будет файлик который надо "заинклюдить", и убедиться что путь выставлен верно и php не ругается. Вот хороший пример.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий