我正在尝试使用PHP创建一个简单的web爬虫,它能够爬行.edu域,提供父域的种子urls。
我使用简单的html dom来实现爬虫,而一些核心逻辑是由我实现的。
我正在张贴下面的代码,并将试图解释问题。
private function initiateChildCrawler($parent_Url_Html) {
global $CFG;
static $foundLink;
static $parentID;
static $urlToCrawl_InstanceOfChildren;
$forEachCount = 0;
foreach($parent_Url_Html->getHTML()->find('a') as $foundLink)
{
$forEachCount++;
if($forEachCount<500) {
$foundLink->href = url_to_absolute($parent_Url_Html->getURL(), $foundLink->href);
if($this->validateEduDomain($foundLink->href))
{
//Implement else condition later on
$parentID = $this->loadSaveInstance->parentExists_In_URL_DB_CRAWL($this->returnParentDomain($foundLink->href));
if($parentID != FALSE)
{
if($this->loadSaveInstance->checkUrlDuplication_In_URL_DB_CRAWL($foundLink->href) == FALSE)
{
$urlToCrawl_InstanceOfChildren = new urlToCrawl($foundLink->href);
if($urlToCrawl_InstanceOfChildren->getSimpleDomSource($CFG->finalContext)!= FALSE)
{
$this->loadSaveInstance->url_db_html($urlToCrawl_InstanceOfChildren->getURL(), $urlToCrawl_InstanceOfChildren->getHTML());
$this->loadSaveInstance->saveCrawled_To_URL_DB_CRAWL(NULL, $foundLink->href, "crawled", $parentID);
/*if($recursiveCount<1)
{
$this->initiateChildCrawler($urlToCrawl_InstanceOfChildren);
}*/
}
}
}
}
}
}
}现在您可以看到,initiateChildCrawler是由initiateParentCrawler函数调用的,它将父链接传递给子爬虫。父链接示例: www.berkeley.edu,爬虫将在其主页上查找所有链接并返回其所有html内容。这种情况一直持续到种子urls耗尽为止。
->>>>>将找到所有链接并返回它们的html内容(通过调用childCrawler)。移到parentCrawler中的下一个父级。2-berkeley.edu ->>>>>将找到所有链接并返回它们的html内容(通过调用childCrawler)。
其他功能是不言自明的。
现在的问题是:在childCrawler完成每个链接的foreach循环之后,函数无法正确退出。如果我从CLI运行脚本,CLI就会崩溃。在浏览器中运行脚本时,脚本将终止。
但是,如果我将爬行子链接的限制设置为10或更少(通过更改$forEachCount变量),爬虫就可以正常工作了。
请在这方面帮助我。
来自CLI的信息:
问题签名:问题事件名称: APPCRASH应用程序名称: php-cgi.exe应用程序版本: 5.3.8.0应用程序时间戳: 4e537939故障模块名称: php5ts.dll故障模块版本: 5.3.8.0故障模块时间戳: 4e537a04异常代码: c0000005异常偏移量: 0000c793操作系统版本: 6.1.7601.2.1.0.256.48地区ID: 1033附加信息1: 0a9e附加信息2: 0a9e372d3b4ad19135b953a78882e789附加信息3: 0a9e附加信息4: 0a9e372d3b4ad19135b953a78882e789
发布于 2011-12-31 13:31:31
平环示例:
(push).
这将一直运行,直到处理完堆栈中的所有URL,因此您添加了一个计数器(就像您在某种程度上已经为foreach添加的那样),以防止它运行太长时间:
$URLStack = (array) $parent_Url_Html->getHTML()->find('a');
$URLProcessedCount = 0;
while ($URLProcessedCount++ < 500) # this can run endless, so this saves us from processing too many URLs
{
$url = array_shift($URLStack);
if (!$url) break; # exit if the stack is empty
# process URL
# for each new URL:
$URLStack[] = $newURL;
}您可以通过不向堆栈中已经存在的堆栈添加URL来使其更加智能化,但是,您只需要将绝对URL插入到堆栈中。然而,我强烈建议您这样做,因为不需要处理您已经获得的页面(例如,每个页面可能包含到主页的链接)。如果要这样做,只需在循环中增加$URLProcessedCount,以便保留以前的条目:
while ($URLProcessedCount < 500) # this can run endless, so this saves us from processing too many URLs
{
$url = $URLStack[$URLProcessedCount++];此外,我建议您使用PHP扩展,而不是简单的DOMDocument,因为它是一个更加通用的工具。
https://stackoverflow.com/questions/8688232
复制相似问题