1. 搜尋政策
① ip 位址搜尋政策
先賦予爬蟲一個起始的ip位址,然後根據ip位址遞增的方式搜尋本ip位址段後的每一個www位址中的文檔,它完全不考慮各文檔中指向其它web 站點的超級連結位址。優點是搜尋全面,能夠發現那些沒被其它文檔引用的新文檔的資訊源;缺點是不适合大規模搜尋。
② 深度優先搜尋政策
深度優先搜尋是一種在開發爬蟲早期使用較多的方法。它的目的是要達到被搜尋結構的葉結點(即那些不包含任何超鍊的html檔案) 。在一個html檔案中,當一個超鍊被選擇後,被連結的html檔案将執行深度優先搜尋,即在搜尋其餘的超鍊結果之前必須先完整地搜尋單獨的一條鍊。深度優先搜尋沿着html檔案上的超鍊走到不能再深入為止,然後傳回到某一個html檔案,再繼續選擇該html檔案中的其他超鍊。當不再有其他超鍊可選擇時,說明搜尋已經結束。優點是能周遊一個web 站點或深層嵌套的文檔集合;缺點是因為web結構相當深,,有可能造成一旦進去,再也出不來的情況發生。
③ 寬度優先搜尋政策
在寬度優先搜尋中,先搜尋完一個web 頁面中所有的超級連結,然後再繼續搜尋下一層, 直到底層為止。例如,一個html 檔案中有三個超鍊,選擇其中之一并處理相應的html檔案,然後不再選擇第二個html檔案中的任何超鍊, 而是傳回并選擇第二個超鍊,處理相應的html檔案,再傳回,選擇第三個超鍊并處理相應的html檔案。一旦一層上的所有超鍊都己被選擇過,就可以開始在剛才處理過的himl 檔案中搜尋其餘的超鍊。這就保證了對淺層的首先處理。當遇到一個無窮盡的深層分支時,不會導緻陷進www 中的深層文檔中出現出不來的情況發生。寬度優先搜尋政策還有一個優點,即它能在兩個html檔案之間找到最短路徑。寬度優先搜尋政策通常是實作爬蟲的最佳政策,因為它容易實作,而且具備大多數期望的功能。但是如果要周遊一個指定的站點或者深層嵌套的html檔案集,用寬度優先搜尋政策則需要花費比較長的時間才能到達深層的html檔案。綜合考慮以上幾種政策和國内資訊導航系統搜尋資訊的特點,國内一般采用以寬度優先搜尋政策為主、線性搜尋政策為輔的搜尋政策。對于某些不被引用的或很少被引用的html檔案,寬度優先搜尋政策可能會遺漏這些孤立的資訊源,可以用線性搜尋政策作為它的補充。
④ 專業搜尋引擎的爬蟲政策
目前,專業搜尋引擎網絡爬蟲通常采用“最好優先”原則通路web,即為快速、有效地獲得更多的與主題相關的頁面(簡稱“回報”),每次選擇“最有價值”的連結進行通路。由于連結包含于頁面之中,而通常具有較高價值的頁面包含的連結也具有較高的價值,因而對連結價值的評價有時也轉換為對頁面價值的評價。
⑤ 爬蟲的設計中應該注意的問題
第一個問題是url位址的标準化:在www上,一個url位址可以有多種表示方法,可以用ip位址表示,也可以用域名來表示。為了避免爬蟲重複通路同一位址。第二個問題是避免掉進網絡陷阱:網絡上的連結情況比較複雜,一些靜态的網頁可能構成閉環回路。為了避免爬蟲在一條循環路線上反複抓取,在把url加入待搜尋位址清單之前都要檢查是否已在待搜尋的位址清單中出現過。對于動态網頁,爬蟲應該忽略所有帶參數的url。第三個問題:對于拒絕通路的頁面,爬蟲應該遵從“漫遊拒絕通路規則”。
create table `grab_history` (
`id` bigint(20) not null auto_increment,
`file_url` varchar(1024) default null,
`url_md5` varchar(40) default null,
primary key (`id`),
key `file_url_md5` (`url_md5`)
) engine=myisam default charset=utf8 comment='grab history';
create table `pic_gallery` (
`id` int(11) not null auto_increment,
`file_url_md5` varchar(100) not null,
`file_data` longblob,
`file_type` varchar(100) default null,
`file_name` varchar(255) default null,
`file_size` int(11) default null,
key `file_url_md5` (`file_url_md5`)
) engine=myisam default charset=utf8;
create table `web_page` (
`page_url_md5` varchar(100) not null,
`page_url` varchar(1024) default null,
`page_content` longblob,
`page_pic` varchar(1024) default null,
`page_length` int(11) default null,
`grab_time` datetime default null,
key `page_url_md5` (`page_url_md5`)
) engine=myisam default charset=utf8 comment='網絡爬蟲資料存儲表';
抓取内容插入資料庫
function put_web_page($url, $content, $filesize) {
$sql = "insert into web_page (page_url_md5, page_url, page_content, page_length, grab_time) values ('".md5($url)."','$url','$content',$filesize,'".date("y-m-d h:i:s", time())."')";
}
抓取圖檔内容插入資料庫
function put_web_pic($url, $content, $filename, $filesize, $ref_page) {
$sql = "insert into pic_gallery (file_url_md5, file_url, file_data, file_name, file_size) values ('".md5($url)."','$url','$content','$filename',$filesize)";
抓取url曆史插入資料庫
function add_history($url, $md5) {
$sql = "insert into grab_history (file_url, url_md5) values ('$url', '$md5');";
function get_grab_history(&$oldhistory, $subkey) {
$sql = "select id, file_url,url_md5 from grab_history where url_md5 like '$subkey%'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
$i;
for ($i = 0; $i < $num; $i++) {
$url = mysql_result($result, $i, 1);
$md5 = mysql_result($result, $i, 2);
//$oldhistory[$url] = $url;
$oldhistory[$md5] = $url;
//if (count($oldhistory) % 1000 == 0) {
// $id = count($oldhistory);
// echo("the size of history is $id!\n");
//}
}
計算網頁中的url路徑資訊
class web_site_info {
var $web_site;
var $web_dir;
var $web_filename;
//解析url
function web_site_info($url) {
$temp = ereg_replace("http://", "", $url);
$sp = split('[/]', $temp);
$sc = count($sp);
echo("$url\n");
$this->web_site = $sp[0];
if ($sc == 1) {
return;
if ($sc == 2) {
$this->web_filename = $sp[1];
}else {
for ($i = 1; $i < $sc -1; $i++) {
if ($i > 1) {
$this->web_dir = $this->web_dir . "/";
}
$this->web_dir = $this->web_dir . $sp[$i];
}
$this->web_filename = $sp[$sc-1];
//分析網頁中的url,建構正确的url
function calc_path($url_path) {
$ret = "";
$temp = "";
$url = trim($url_path);
$pos = strncmp($url, "http://", 7);
if ($pos == 0) {
return $url;
$pos = strncmp($url, "../", 3);
$ret = $this->web_site ."/" .$this->web_dir;
$ret = dirname($ret);
$ret = "http://" .$ret ."/";
$temp = ereg_replace("../", $ret, $url);
return $temp;
$pos = strncmp($url, "./", 2);
$ret = "http://" .$this->web_site ."/";
if (strlen($this->web_dir) > 0)
$ret = $ret .$this->web_dir ."/";
$temp = ereg_replace("./", $ret, $url);
$pos = strncmp($url, "/", 1);
$ret = "http://" .$this->web_site .$url;
return $ret;
$ret = "http://" .$this->web_site ."/";
if (strlen($this->web_dir) > 0) {
$ret = $ret .$this->web_dir ."/";
$ret = $ret .$url;
return $ret;
//擷取url中的路徑名
function get_save_path() {
$ret;
if (strlen($this->web_dir)) {
$ret = $this->web_site."\\".$this->web_dir;
$ret = $this->web_site;
$ret = ereg_replace("/", "\\", $ret);
//擷取url中的檔案名
function get_save_filename() {
$ret = $this->get_save_path();
if (strlen($this->web_filename) == 0) {
$ret = $ret."\\index.html";
$ret = $ret ."\\".$this->web_filename;
}
抓取網頁
<?php
class web_crawl_job {
var $m_level;
var $m_url;
var $url_info;
var $sub_job;
var $page_images;
var $dbc;
var $m_max_deep;
return $this->url_info->get_save_filename();
function sub_job_count() {
return count($this->sub_job);
function do_sub_job() {
global $global_download;
//計算總任務數
$count = count($this->sub_job);
for ($i = 0; $i < $count; $i++) {
$url = $this->url_info->calc_path($this->sub_job[$i]);
if ($global_download->have_key($url)) {
echo "have downloaded: ".$url ."\n";
continue;
$pos = strpos($url, "http://");
if ($pos === false) {
echo "error url: $url\n";
}else {
//$global_download->add_key($url);
$sub = new web_crawl_job($url, $this->m_level + 1, $this->dbc, $this->m_max_deep);
unset($sub);
sleep(2);
//下載下傳圖檔
function down_page_pic() {
$count = count($this->page_images);
$url = $this->url_info->calc_path($this->page_images[$i]);
echo "error image url: $url\n";
echo $url."\n";
//$global_download[$url] = $url;
$global_download->add_key($url);
$content = file_get_contents($url);
if (strlen($content) == 0) {
continue;
$retry_count = 0;
while (strlen($content) == 0) {
if ($retry_count++ >= 2) {
break;
}
sleep(1);
$content = file_get_contents($url);
}
$this->dbc->put_web_pic($url, addslashes($content), basename($url), strlen($content), $this->m_url);
function web_crawl_job($url, $level, $db_in_op, $m_dp) {
$this->m_level = $level;
$this->m_url = $url;
$this->url_info = new web_site_info($url);
$this->dbc = $db_in_op;
$this->m_max_deep = $m_dp;
echo "my level is:" .$level ."\n";
//檢查内容是否為空
$content = file_get_contents($url);
if (strlen($content) == 0) {
$retry_count = 0;
while(strlen($content) == 0) {
sleep(10);
$retry_count = $retry_count + 1;
if ($retry_count > 3) {
$global_download->add_key($url);
return;
$md5_str;
//取出頁面中的url放到任務裡面
//分析連結
$reg = "#<a[^>]+href=(['\"])(.+)\\1#isu";
preg_match_all($reg, $content, $m);
foreach($m[2] as $src) {
$this->sub_job[] = $src;
//分析圖檔
$reg = "#<img[^>]+src=(['\"])(.+)\\1#isu";
preg_match_all($reg, $content, $m);
foreach($m[2] as $src) {
$this->page_images[] = $src;
$db_in_op->put_web_page($url, addslashes($content), strlen($content));
$this->down_page_pic();
$global_download->add_key($url);
if ($this->m_level < $this->m_max_deep and count($this->sub_job) > 0) {
//執行子任務
$this->do_sub_job();
?>
//檢查連結是否被抓取過
class web_grab_history {
var $m_db_op;
var $m_oldhistory;
var $m_newhistory;
var $m_subkey;
function __construct($db_op) {
$this->m_db_op = $db_op;
//$db_op->get_grab_history($this->m_oldhistory);
//儲存連結曆史
function save_history() {
foreach($this->m_newhistory as $md5 => $url) {
$this->m_db_op->add_history($url, $md5);
//從資料庫查詢對外連結接曆史
function load_subkey($subkey) {
$this->m_subkey[$subkey] = $subkey;
$this->m_db_op->get_grab_history($this->m_oldhistory, $subkey);
function __destruct() {}
function have_key($url) {
$ret = false;
$md5 = md5($url);
$subkey = $md5[0] .$md5[1] .$md5[2];
if (strstr($url, "rar") > 0) {
return true;
//先從記憶體中查詢連結
if (count($this->m_subkey) > 0 && array_key_exists($subkey, $this->m_subkey) == true) {
$this->load_subkey($subkey);
if (count($this->m_oldhistory)) {
//$ret |= array_key_exists($url, $this->m_oldhistory);
$ret |= array_key_exists($md5, $this->m_oldhistory);
if ($ret == true) {
if (count($this->m_newhistory)) {
//$ret |= array_key_exists($url, $this->m_newhistory);
$ret |= array_key_exists($md5, $this->m_newhistory);
return $ret;
//添加連結曆史
function add_key($url) {
//$this->m_newhistory[$url] =$url;
$this->m_newhistory[$md5] = $url;
if (count($this->m_newhistory) > 400) {
//
}
//入口
function print_use()
{
echo "usage:\nphp -f deepth spider.php url\n";
if ($argc == 1) {
print_use();
die;
$global_grab_deep = (int)$argv[1];
$url = $argv[2];
$db_op = new my_insert();
//擷取抓取db連結
$global_download = new web_grab_history($db_op);
//開始抓取
$tt = new web_crawl_job($url, 1, $db_op, $global_grab_deep);
//儲存抓取曆史
$global_download->save_history();
echo "mission complished!\n";