spider 介绍

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介:

Spider又叫WebCrawler或者Robot,是一个沿着链接漫游Web 文档集合的程序。它一般驻留在服务器上,通过给定的一些URL,利用HTTP等标准协议读取相应文档,然后以文档中包括的所有未访问过的URL作为新的起点,继续进行漫游,直到没有满足条件的新URL为止。WebCrawler的主要功能是自动从Internet上的各Web 站点抓取Web文档并从该Web文档中提取一些信息来描述该Web文档,为搜索引擎站点的数据库服务器追加和更新数据提供原始数据,这些数据包括标题、长度、文件建立时间、HTML文件中的各种链接数目等
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。第三个问题:对于拒绝访问的页面,爬虫应该遵从“漫游拒绝访问规则”。

Java代码   收藏代码
  1. CREATE TABLE `grab_history` (  
  2.   `id` bigint(20) NOT NULL auto_increment,  
  3.   `file_url` varchar(1024default NULL,  
  4.   `url_md5` varchar(40default NULL,  
  5.   PRIMARY KEY  (`id`),  
  6.   KEY `file_url_md5` (`url_md5`)  
  7. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='grab history';  
  8.   
  9. CREATE TABLE `pic_gallery` (  
  10.   `id` int(11) NOT NULL auto_increment,  
  11.   `file_url_md5` varchar(100) NOT NULL,  
  12.   `file_url` varchar(1024default NULL,  
  13.   `file_data` longblob,  
  14.   `file_type` varchar(100default NULL,  
  15.   `file_name` varchar(255default NULL,  
  16.   `file_size` int(11default NULL,  
  17.   PRIMARY KEY  (`id`),  
  18.   KEY `file_url_md5` (`file_url_md5`)  
  19. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;  
  20.   
  21. CREATE TABLE `web_page` (  
  22.   `id` bigint(20) NOT NULL auto_increment,  
  23.   `page_url_md5` varchar(100) NOT NULL,  
  24.   `page_url` varchar(1024default NULL,  
  25.   `page_content` longblob,  
  26.   `page_pic` varchar(1024default NULL,  
  27.   `page_length` int(11default NULL,  
  28.   `grab_time` datetime default NULL,  
  29.   PRIMARY KEY  (`id`),  
  30.   KEY `page_url_md5` (`page_url_md5`)  
  31. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='网络爬虫数据存储表';  
 
Java代码   收藏代码
  1. 抓取内容插入数据库     
  2. function put_web_page($url, $content, $filesize) {  
  3.         $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())."')";  
  4.     }  
  5.    抓取图片内容插入数据库  
  6.     function put_web_pic($url, $content, $filename, $filesize, $ref_page) {  
  7.         $sql = "insert into pic_gallery (file_url_md5, file_url, file_data, file_name, file_size) values ('".md5($url)."','$url','$content','$filename',$filesize)";  
  8.     }  
  9. 抓取url历史插入数据库  
  10.     function add_history($url, $md5) {  
  11.         $sql = "insert into grab_history (file_url, url_md5) values ('$url', '$md5');";  
  12.     }  
  13.       
  14.     function get_grab_history(&$oldhistory, $subkey) {  
  15.         $sql = "select id, file_url,url_md5 from grab_history where url_md5 like '$subkey%'";  
  16.         $result = mysql_query($sql);  
  17.         $num = mysql_num_rows($result);  
  18.         $i;  
  19.         for ($i = 0; $i < $num; $i++) {  
  20.             $url = mysql_result($result, $i, 1);  
  21.             $md5 = mysql_result($result, $i, 2);  
  22.             //$oldhistory[$url] = $url;  
  23.             $oldhistory[$md5] = $url;  
  24.             //if (count($oldhistory) % 1000 == 0) {  
  25.             //    $id = count($oldhistory);  
  26.             //    echo("the size of history is $id!\n");  
  27.             //}  
  28.         }  
  29.     }  

 计算网页中的url路径信息

Java代码   收藏代码
  1. class web_site_info {  
  2.     var $web_site;  
  3.     var $web_dir;  
  4.     var $web_filename;  
  5.   
  6. //解析URL  
  7.     function web_site_info($url) {  
  8.         $temp = ereg_replace("http://""", $url);  
  9.         $sp = split('[/]', $temp);  
  10.         $sc = count($sp);  
  11.         $i;  
  12.   
  13.         echo("$url\n");  
  14.    
  15.         $this->web_site = $sp[0];  
  16.    
  17.         if ($sc == 1) {  
  18.             return;  
  19.         }  
  20.    
  21.         if ($sc == 2) {  
  22.             $this->web_filename = $sp[1];  
  23.         }else {  
  24.             for ($i = 1; $i < $sc -1; $i++) {  
  25.                 if ($i > 1) {  
  26.                     $this->web_dir = $this->web_dir . "/";  
  27.                 }  
  28.                 $this->web_dir =  $this->web_dir . $sp[$i];  
  29.             }  
  30.             $this->web_filename = $sp[$sc-1];  
  31.         }  
  32.     }  
  33. //分析网页中的url,构建正确的url  
  34.     function calc_path($url_path) {  
  35.         $ret = "";  
  36.         $temp = "";  
  37.         $url = trim($url_path);  
  38.         $pos = strncmp($url, "http://"7);  
  39.         if ($pos == 0) {  
  40.             return $url;  
  41.         }  
  42.          
  43.         $pos = strncmp($url, "../"3);  
  44.         if ($pos == 0) {  
  45.             $ret = $this->web_site ."/" .$this->web_dir;  
  46.             $ret = dirname($ret);  
  47.             $ret = "http://" .$ret ."/";  
  48.             $temp = ereg_replace("../", $ret, $url);  
  49.             return $temp;  
  50.         }  
  51.          
  52.         $pos = strncmp($url, "./"2);  
  53.         if ($pos == 0) {  
  54.             $ret = "http://" .$this->web_site ."/";  
  55.             if (strlen($this->web_dir) > 0)  
  56.                 $ret = $ret .$this->web_dir ."/";  
  57.             $temp = ereg_replace("./", $ret, $url);  
  58.             return $temp;  
  59.         }  
  60.          
  61.         $pos = strncmp($url, "/"1);  
  62.         if ($pos == 0) {  
  63.             $ret = "http://" .$this->web_site .$url;  
  64.             return $ret;  
  65.         }  
  66.          
  67.         $ret = "http://" .$this->web_site ."/";  
  68.         if (strlen($this->web_dir) > 0) {  
  69.             $ret = $ret .$this->web_dir ."/";  
  70.         }  
  71.         $ret = $ret .$url;  
  72.         return $ret;  
  73.          
  74.     }  
  75.  //获取url中的路径名  
  76.     function get_save_path() {  
  77.         $ret;  
  78.         if (strlen($this->web_dir)) {  
  79.             $ret = $this->web_site."\\".$this->web_dir;  
  80.         }else {  
  81.             $ret = $this->web_site;  
  82.         }  
  83.    
  84.         $ret = ereg_replace("/""\\", $ret);  
  85.         return $ret;  
  86.     }  
  87.  //获取url中的文件名  
  88.     function get_save_filename() {  
  89.         $ret = $this->get_save_path();  
  90.         if (strlen($this->web_filename) == 0) {  
  91.             $ret = $ret."\\index.html";  
  92.         }else {  
  93.             $ret = $ret ."\\".$this->web_filename;  
  94.         }  
  95.         $ret = ereg_replace("/""\\", $ret);  
  96.         return $ret;  
  97.     }  
  98. }  

 抓取网页

Java代码   收藏代码
  1. <?php  
  2. class web_crawl_job {  
  3.     var $m_level;  
  4.     var $m_url;  
  5.     var $url_info;  
  6.     var $sub_job;  
  7.     var $page_images;  
  8.     var $dbc;  
  9.     var $m_max_deep;  
  10.    
  11.     function get_save_filename() {  
  12.         return $this->url_info->get_save_filename();  
  13.     }  
  14.    
  15.    
  16.     function sub_job_count() {  
  17.         return count($this->sub_job);  
  18.     }  
  19.    
  20.     function do_sub_job() {  
  21.         $i;  
  22.         global $global_download;  
  23. //计算总任务数  
  24.         $count = count($this->sub_job);  
  25.         for ($i = 0; $i < $count; $i++) {  
  26.             $url = $this->url_info->calc_path($this->sub_job[$i]);  
  27.   
  28.             if ($global_download->have_key($url)) {  
  29.                 echo "have downloaded: ".$url ."\n";  
  30.                 continue;  
  31.             }  
  32.              
  33.             $pos = strpos($url, "http://");  
  34.             if ($pos === false) {  
  35.                 echo "error url: $url\n";  
  36.             }else {  
  37.                 //$global_download->add_key($url);  
  38.                 $sub = new web_crawl_job($url, $this->m_level + 1, $this->dbc, $this->m_max_deep);  
  39.                 unset($sub);  
  40.             }  
  41.             sleep(2);  
  42.         }  
  43.     }  
  44.     //下载图片  
  45.     function down_page_pic() {  
  46.         $i;  
  47.         global $global_download;  
  48.         $count = count($this->page_images);  
  49.         for ($i = 0; $i < $count; $i++) {  
  50.             $url = $this->url_info->calc_path($this->page_images[$i]);  
  51.             if ($global_download->have_key($url)) {  
  52.                 echo "have downloaded: ".$url ."\n";  
  53.                 continue;  
  54.             }  
  55.             $pos = strpos($url, "http://");  
  56.             if ($pos === false) {  
  57.                 echo "error image url: $url\n";  
  58.             }else {  
  59.                 echo $url."\n";  
  60.                 //$global_download[$url] = $url;  
  61.                 $global_download->add_key($url);  
  62.                 $content = file_get_contents($url);  
  63.                 if (strlen($content) == 0) {  
  64.                     continue;  
  65.                 }  
  66.                 if (strlen($content) == 0) {  
  67.                     $retry_count = 0;  
  68.                     while (strlen($content) == 0) {  
  69.                         if ($retry_count++ >= 2) {  
  70.                             break;  
  71.                         }  
  72.                         sleep(1);  
  73.                         $content = file_get_contents($url);                     
  74.                     }  
  75.                 }  
  76.                 $this->dbc->put_web_pic($url, addslashes($content), basename($url), strlen($content), $this->m_url);  
  77.             }  
  78.         }  
  79.     }  
  80.    
  81.     function web_crawl_job($url, $level, $db_in_op, $m_dp) {  
  82.         $this->m_level = $level;  
  83.         $this->m_url = $url;  
  84.         $this->url_info = new web_site_info($url);  
  85.         $this->dbc = $db_in_op;  
  86.         $this->m_max_deep = $m_dp;  
  87.         global $global_download;  
  88.   
  89.      
  90.         echo "My Level is:" .$level ."\n";  
  91.   
  92.        //检查内容是否为空  
  93.         $content = file_get_contents($url);  
  94.         if (strlen($content) == 0) {  
  95.             $retry_count = 0;  
  96.             while(strlen($content) == 0) {  
  97.                 sleep(10);  
  98.                 $content = file_get_contents($url);  
  99.                 $retry_count = $retry_count + 1;  
  100.                 if ($retry_count > 3) {  
  101.                     $global_download->add_key($url);  
  102.                     return;  
  103.                 }  
  104.             }  
  105.         }  
  106.         $md5_str;  
  107.   
  108.         //取出页面中的url放到任务里面  
  109. //分析链接  
  110.        $reg = "#<a[^>]+href=(['\"])(.+)\\1#isU";  
  111.         preg_match_all($reg,   $content,   $m);  
  112.         foreach($m[2]   as   $src) {  
  113.             $this->sub_job[] = $src;  
  114.         }  
  115. //分析图片  
  116.         $reg   =   "#<img[^>]+src=(['\"])(.+)\\1#isU";  
  117.         preg_match_all($reg, $content, $m);  
  118.         foreach($m[2] as $src) {  
  119.             $this->page_images[] = $src;  
  120.         }  
  121.         $db_in_op->put_web_page($url, addslashes($content), strlen($content));  
  122.         $this->down_page_pic();  
  123.          
  124.         $global_download->add_key($url);  
  125.          
  126.         if ($this->m_level < $this->m_max_deep and count($this->sub_job) > 0) {  
  127. //执行子任务  
  128.             $this->do_sub_job();  
  129.         }  
  130.     }  
  131. }  
  132.   
  133. ?>  
  134.   
  135.       
  136. //检查链接是否被抓取过  
  137. class web_grab_history {  
  138.     var $m_db_op;  
  139.     var $m_oldhistory;  
  140.     var $m_newhistory;  
  141.     var $m_subkey;  
  142.      
  143.     function __construct($db_op) {  
  144.         $this->m_db_op = $db_op;  
  145.         //$db_op->get_grab_history($this->m_oldhistory);  
  146.     }  
  147.     //保存链接历史  
  148.     function save_history() {  
  149.         foreach($this->m_newhistory as $md5 => $url) {  
  150.             $this->m_db_op->add_history($url, $md5);  
  151.         }  
  152.     }  
  153. //从数据库查询出链接历史  
  154.     function load_subkey($subkey) {  
  155.         $this->m_subkey[$subkey] = $subkey;  
  156.         $this->m_db_op->get_grab_history($this->m_oldhistory, $subkey);  
  157.     }  
  158.      
  159.     function __destruct() {}  
  160.      
  161.     function have_key($url) {  
  162.         $ret = false;  
  163.         $md5 = md5($url);  
  164.         $subkey = $md5[0] .$md5[1] .$md5[2];  
  165.   
  166.   
  167.         if (strstr($url, "rar") > 0) {  
  168.             return true;  
  169.         }  
  170. //先从内存中查询链接  
  171.         if (count($this->m_subkey) > 0 && array_key_exists($subkey, $this->m_subkey) == true) {  
  172.         }else {  
  173.             $this->load_subkey($subkey);  
  174.         }  
  175.          
  176.          
  177.         if (count($this->m_oldhistory)) {  
  178.             //$ret |= array_key_exists($url, $this->m_oldhistory);  
  179.             $ret |= array_key_exists($md5, $this->m_oldhistory);  
  180.         }  
  181.   
  182.         if ($ret == true) {  
  183.             return $ret;  
  184.         }  
  185.          
  186.         if (count($this->m_newhistory)) {  
  187.             //$ret |= array_key_exists($url, $this->m_newhistory);  
  188.             $ret |= array_key_exists($md5, $this->m_newhistory);  
  189.         }  
  190.         return $ret;         
  191.     }  
  192.     //添加链接历史  
  193.     function add_key($url) {  
  194.         $md5 = md5($url);  
  195.         //$this->m_newhistory[$url] =$url;  
  196.         $this->m_newhistory[$md5] = $url;  
  197.         if (count($this->m_newhistory) > 400) {  
  198.             //  
  199.         }     
  200.     }  
  201.      
  202.      
  203. }  
 
Java代码   收藏代码
  1. //入口  
  2. function print_use()  
  3. {  
  4.  echo "Usage:\nphp -f deepth spider.php url\n";  
  5. }  
  6. if ($argc == 1) {  
  7.  print_use();  
  8.  die;  
  9. }  
  10. $global_grab_deep = (int)$argv[1];  
  11. $url = $argv[2];  
  12. $db_op = new my_insert();  
  13. //获取抓取DB链接  
  14. $global_download = new web_grab_history($db_op);  
  15. //开始抓取  
  16. $tt = new web_crawl_job($url, 1, $db_op, $global_grab_deep);  
  17. //保存抓取历史  
  18. $global_download->save_history();  
  19. echo "Mission Complished!\n";  
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
数据采集 中间件 Python
scrapy中使用senlenium
scrapy中使用senlenium
20 0
|
6月前
|
数据采集 存储 数据挖掘
scrapy介绍
scrapy介绍
60 0
|
数据采集 JSON 前端开发
Scrapy 的初步认识
Scrapy 是一个高级的 Python 爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫获取的数据保存到 csv、json 等文件中。 Scrapy 使用了 Twisted 作为框架,Twisted 是事件驱动的,对于会阻塞线程的操作(访问文件、数据库等),比较适合异步的代码。
|
Python
Scrapy中get和extract_first的区别
Scrapy中get和extract_first的区别
89 0
|
数据采集 存储 JSON
scrapy学习
scrapy学习
157 0
|
数据采集 前端开发 数据库
Scrapy框架| Scrapy中spiders的那些事......
Scrapy框架| Scrapy中spiders的那些事......
90 0
|
XML Ubuntu 安全
二、安装 Scrapy
二、安装 Scrapy
180 0
|
数据采集 算法 中间件
scrapy相关专题总结
本月的scrapy已经写完,关于scrapy写了常用的中间件、数据管道、以及scrapy的相关源码,但是感觉可写的内容不是很多,要门是使用相关的要么是一些不用关注的源码。 所以写完scrapy之后还写了些一些其他内容,算是在充数吧,同时预下一个专题是python的数据结构和算法,将对九大算法及其常用数据结构分享,同时将算法应用于数据结构上。
1669 0
Scrapy框架的使用之Spider的用法
在Scrapy中,要抓取网站的链接配置、抓取逻辑、解析逻辑里其实都是在Spider中配置的。在前一节实例中,我们发现抓取逻辑也是在Spider中完成的。本节我们就来专门了解一下Spider的基本用法。
|
前端开发 Python Shell
使用scrapy抓取股票代码
个人博客:https://mypython.me 源码地址:https://github.com/geeeeeeeek/scrapy_stock 抓取工具:scrapy scrapy介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。
2780 0

热门文章

最新文章