У меня есть веб-страница с набором ссылок. Я хочу записать сценарий, который вывел бы все данные, содержавшиеся в тех ссылках в локальном файле.
Кто-либо сделал это с PHP? Общие руководящие принципы и глюки были бы достаточны как ответ.
Мех. Не анализируйте HTML с помощью регулярных выражений .
Вот версия DOM, вдохновленная Тату:
<?php
function crawl_page($url, $depth = 5)
{
static $seen = array();
if (isset($seen[$url]) || $depth === 0) {
return;
}
$seen[$url] = true;
$dom = new DOMDocument('1.0');
@$dom->loadHTMLFile($url);
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $element) {
$href = $element->getAttribute('href');
if (0 !== strpos($href, 'http')) {
$path = '/' . ltrim($href, '/');
if (extension_loaded('http')) {
$href = http_build_url($url, array('path' => $path));
} else {
$parts = parse_url($url);
$href = $parts['scheme'] . '://';
if (isset($parts['user']) && isset($parts['pass'])) {
$href .= $parts['user'] . ':' . $parts['pass'] . '@';
}
$href .= $parts['host'];
if (isset($parts['port'])) {
$href .= ':' . $parts['port'];
}
$href .= dirname($parts['path'], 1).$path;
}
}
crawl_page($href, $depth - 1);
}
echo "URL:",$url,PHP_EOL,"CONTENT:",PHP_EOL,$dom->saveHTML(),PHP_EOL,PHP_EOL;
}
crawl_page("http://hobodave.com", 2);
Редактировать: Я исправил некоторые ошибки в версии Тату (теперь работает с относительными URL-адресами).
Изменить: Я добавил новую функциональность, которая не позволяет ему дважды переходить по одному и тому же URL-адресу.
Редактировать: теперь выводят вывод в STDOUT, чтобы вы могли перенаправить его в любой файл, который хотите
Редактировать: Исправлена ошибка, указанная Джорджем в его ответе. Относительные URL-адреса больше не будут добавляться в конец пути URL-адреса, а будут перезаписывать его. Спасибо Джорджу за это. Обратите внимание, что ответ Джорджа не учитывает ни https, ни пользователя, ни пароль, ни порт. Если у вас загружено расширение http PECL, это довольно просто сделать с помощью http_build_url . В противном случае мне придется вручную склеивать с помощью parse_url. Еще раз спасибо, Джордж.
Зачем использовать PHP для этого, когда можно использовать wget, например
wget -r -l 1 http://www.example.com
О том, как разобрать содержимое, смотрите Лучшие методы разбора HTML и используйте функцию поиска примеров. На вопрос о том, как разобрать HTML, мы уже неоднократно отвечали.
В простейшей форме:
function crawl_page($url, $depth = 5) {
if($depth > 0) {
$html = file_get_contents($url);
preg_match_all('~<a.*?href="(.*?)".*?>~', $html, $matches);
foreach($matches[1] as $newurl) {
crawl_page($newurl, $depth - 1);
}
file_put_contents('results.txt', $newurl."\n\n".$html."\n\n", FILE_APPEND);
}
}
crawl_page('http://www.domain.com/index.php', 5);
Эта функция получит содержимое страницы, затем просканирует все найденные ссылки и сохранит содержимое в 'results.txt' . Функции принимают второй параметр, глубину, который определяет, как долго следует переходить по ссылкам. Передайте 1, если хотите анализировать только ссылки с данной страницы.
Как уже упоминалось, есть фреймворки для поисковых роботов, все готовые для настройки, но если то, что вы делаете, как вы упомянули, вы можете довольно легко сделать это с нуля.
Очистка ссылок: http://www.phpro.org/examples/Get-Links-With-DOM.html
Выгрузка результатов в файл: http: //www.tizag .com / phpT / filewrite.php
Ознакомьтесь с PHP Crawler
http://sourceforge.net/ projects / php-crawler /
Посмотрим, поможет ли это.