我正在尝试创建一个网络爬虫。我发现了一个非常有用的网站,但有一个问题。它只在一个页面中找到链接,而我想在整个网站中找到所有的链接,子链接,而不仅仅是一个页面。经过一段时间的研究,我在一些网站上看到有人建议创建循环函数,调用过程中的过程。
在我这样做之后,又出现了另一个问题,有太多重复的链接,php代码因为没有分配足够的内存而出错。我尝试了几种方法来消除重复链接,但都不起作用。我最好的方法是使用这个数组,不在数组中的链接将被保留,而已经在数组中中的链接则将被忽略。但到目前为止,情况仍然不好。
可能有人能帮我吗?这是我的密码。
ini_set('memory_limit','1024M');
include_once('simple_html_dom.php');
$urlarray = array();
$a=0;
function crawl_page($target_url, $urlarray){
$html = new simple_html_dom();
$html->load_file($target_url);
foreach($html->find('a') as $link)
{
if (!in_array($link->href, $urlarray)) {
$arraysize = sizeof($urlarray);
echo $link->href."<br />";
$urlarray[$arraysize] = $link->href;
crawl_page($link->href, $urlarray);
}
}
}
$url[0]= "http://www.lazada.co.id";
crawl_page("http://www.lazada.co.id", $url);
结果是:
(!)致命错误:第555 行的C:''wamp''www''testcrawler''simple_html_dom.php中超过了120秒的最长执行时间
更新:
我已经解决了。我在stackoverflow的某个地方找到了有同样问题的链接。有人建议不要使用递归模型,而是使用队列模型。所以我将代码修改为队列模型,它就起作用了。现在我写这篇文章的时候,我的网络爬虫运行得很好。
Web爬网不仅仅是从网页中提取数据。。但正如你在问题中提到的,我想你只是想从网页中提取一些元素
因此,PHP有phpQuery库来交互提取网页。。它不是php中唯一的库,但却是最受欢迎的
我希望能帮助你
在速度方面,我想没有什么能比得上旧的strpos
和substr
组合。
这基本上很不方便,但我已经用这种方法编写了几个爬网程序,我怀疑它在技术上是否能比PHP更快。
这里有一个简单的例子:
function extractVideoURL(&$html,$start)
{
$value = strpos($html,'meta name="twitter:player:stream" content="',$start)+strlen('meta name="twitter:player:stream" content="');
$end = strpos($html,'"',$value);
$URL = substr($html,$value,$end-$value);
return $URL;
}
此外,内存开销相当低,因为您不需要将HTML解析为另一个结构。
以下是PHP Web爬网程序的完整代码和解释,让我们开始吧:
<?php
// set user agent
ini_set('user_agent', 'NameOfAgent (http://www.example.net)');
//initializing url to crawl
$url = "http://www.example.net/somepage.html";
//checking robots.txt and extracting more links, sublinks from url
if(robots_allowed($url, "NameOfAgent")) {
$input = @file_get_contents($url) or die("Could not access file: $url");
$regexp = "<a's[^>]*href=('"??)([^'" >]*?)''1[^>]*>(.*)<'/a>";
if(preg_match_all("/$regexp/siU", $input, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
// $match[2] = link address it means that will show you link title
// $match[3] = link text it means that will show you link title
}
}
} else {
die('Access denied by robots.txt');
}
//function for extracting title, keywords, description from url
function file_get_contents_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$html = file_get_contents_curl($url);
//parsing begins here:
$doc = new DOMDocument();
@$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName('title');
//get and display what you need:
$title = $nodes->item(0)->nodeValue;
$metas = $doc->getElementsByTagName('meta');
for ($i = 0; $i < $metas->length; $i++)
{
$meta = $metas->item($i);
if($meta->getAttribute('name') == 'description')
$description = $meta->getAttribute('content');
if($meta->getAttribute('name') == 'keywords')
$keywords = $meta->getAttribute('content');
}
}
希望能有所帮助。