Php 递归站点爬虫
有几个现有的网站,我需要将所有的URL和内容输入Elasticsearch,因此通过一些示例,我构建了一种方法来获取网站上的所有内部链接,并将它们放入一个数组中。问题是我看到的每个例子都不是完全递归的,有一个深度设置。在过去的6个小时里,我一直在(认真地)尝试各种不同的方法使它完全递归。我现在是这样做的,但我认为我正在无限循环和崩溃,因为在运行一分钟后,我没有收到任何错误,只有一个“没有收到数据”页面。我愿意接受任何关于更好方法的建议Php 递归站点爬虫,php,recursion,Php,Recursion,有几个现有的网站,我需要将所有的URL和内容输入Elasticsearch,因此通过一些示例,我构建了一种方法来获取网站上的所有内部链接,并将它们放入一个数组中。问题是我看到的每个例子都不是完全递归的,有一个深度设置。在过去的6个小时里,我一直在(认真地)尝试各种不同的方法使它完全递归。我现在是这样做的,但我认为我正在无限循环和崩溃,因为在运行一分钟后,我没有收到任何错误,只有一个“没有收到数据”页面。我愿意接受任何关于更好方法的建议 <?php set_time_limi
<?php
set_time_limit (1209600);
ini_set('memory_limit', '-1');
$seen = array();
$urls = crawl_page("http://example.com", $seen);
foreach($urls as $url){
echo $url.'<br />';
}
function crawl_page($url, $seen){
//CURL TO GRAB PAGE
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$result = curl_exec ($ch);
curl_close ($ch);
//URL NO HTTP/S OR WWW
$urlStripped = str_replace('www', '', $url);
$urlStripped = str_replace('http://', '', $urlStripped);
$urlStripped = str_replace('https://', '', $urlStripped);
//ADD THIS URL TO THE ARRAY
if(!in_array($url, $seen)){
$seen[] = $url;
}
//GET ALL LINKS IN PAGE
$stripped_file = strip_tags($result, "<a>");
preg_match_all("/<a[\s]+[^>]*?href[\s]?=[\s\"\']+"."(.*?)[\"\']+.*?>"."([^<]+|.*?)?<\/a>/", $stripped_file, $matches, PREG_SET_ORDER );
foreach($matches as $match){
$href = $match[1];
//MAKE SURE LINK ISNT DUPLICATE AND MAKE SURE THE LINK IS INTERNAL
if(!in_array($href, $seen) && is_in_string($urlStripped, $href)){
$seen[] = $href;
}
}
//HERE'S WHERE THE PROBLEM LIES, ATTEMPTING TO MAKE THIS RECURSIVE.
//I'VE DONE THIS MANY DIFFERENT WAYS WITH NO LUCK.
//I DON'T REALLY HAVE A REASON FOR IT'S CURRENT STATE.
//I ENDED UP TAKING SHOTS IN THE DARK AND THATS WHAT LED ME TO ASK ON STACKOVERFLOW
$seenTemp1 = $seen;
foreach($seenTemp1 as $aUrl){
$seenTemp2 = crawl_page($aUrl, $seenTemp1);
$seen = array_merge($seen, $seenTemp2);
}
//RETRUN ARRAY
return $seen;
}
function is_in_string($needle, $string){
$before = strlen($string);
$after = strlen(str_replace($needle, '', $string));
if($before != $after){
return true;
}
else{
return false;
}
}
?>
Yeah的可能重复,但我如何在PHP中做到这一点,以便在最后我可以循环通过最终数组并将这些URL插入到附加到弹性搜索的数据库中。你总是希望有一个深度设置,否则你可能会被困在蜂蜜陷阱网站上(它们有无限的深度)。我在这里没有看到任何sleep()
——如果您不想在其他人的web服务器上造成拒绝服务,您应该添加这一点。至于这个问题,调试出了什么结果?深度(比如说)5应该可以满足大多数网站的需求,在重复出现的时候就打折。在foreach
循环中复制和修改$seen
的方式看起来有点复杂。用一些已知的测试数据跟踪这个,你可能会在这里发现一个bug。好的,我将使用深度设置来尝试这个,我想我应该在每一页上睡觉(2)。我会发布结果。