<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[北京SEO_北京SEO培训 - 【元创SEO】]]></title> 
<link>http://www.yuan-chuang.cc/index.php</link> 
<description><![CDATA[元创拥有10多年网络营销和SEO实战经验、管理经验。 《SEO实战 - 核心技术、优化策略、流量提升》一书作者。SEO实战家、推一把联合创始人]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[北京SEO_北京SEO培训 - 【元创SEO】]]></copyright>
<item>
<link>http://www.yuan-chuang.cc/read.php/.htm</link>
<title><![CDATA[小健讲座:搜索引擎与Web Spider原理详解]]></title> 
<author>元创 &lt;admin@yourname.com&gt;</author>
<category><![CDATA[SEO策略]]></category>
<pubDate>Fri, 18 Sep 2009 13:34:41 +0000</pubDate> 
<guid>http://www.yuan-chuang.cc/read.php/.htm</guid> 
<description>
<![CDATA[ 
	<strong>小健讲座:搜索引擎与Web Spider原理详解</strong><br/><br/>网络蜘蛛(Web Spider)程序的实现是一个比较复杂而且有一些技术难点的工作，通过一段时间对其的研究，以及对完成一些数据抓取的用例进行了归纳总结，现详细说明给其实现原理及技术难点讲解给大家。<br/>任意给一个入口即链接，便可以访问整个互联网，这就是网络蜘蛛(Web Spider)的最终目标，当然这对于像GOOGLE，BAIDU，yahoo等一些搜索引擎的蜘蛛来说，肯定是需要做到这一点的。<br/>但对于我们目前的情况来说，不需要访问整个互联网，而我们只需要提取我们所需要的信息就可以了，那么对于网络蜘蛛(Web Spider)的关键点不是抓取网页数据，而是分析网页数据。<br/>对于每个网页五花八门的数据格式，要分析出所需要的数据则是一件令人头痛的问题，接下来我们先说说整个实现流程，然后针对每一个步骤详细来说明<br/>一下其实现原理及方法。<br/>二. 网络蜘蛛基本原理<br/>网络蜘蛛即 Web Spider，是一个很形象的名字呵呵。<br/>把互联网比喻成一个蜘蛛网，那么Spider就是在网上爬来爬去的蜘蛛。<br/>网络蜘.蛛是通过网页的链接地址来寻找网页，从网站某一个页面（通常是首页）开始爬入，读取网页的内容，找到在网页中的其它链接地址 ，然后通过这些链接地址寻找下一个网页，这样一直循环下去，直到把这个网站所有的网页都抓取完为止。<br/><br/>网络蜘.蛛是通过网页的链接地址来寻找网页，从网站某一个页面（通常是首页）开始爬入，读取网页的内容，找到在网页中的其它链接地址 ，然后通过这些链接地址寻找下一个网页，这样一直循环下去，直到把这个网站所有的网页都抓取完为止。<br/>如果把整个互联网当成一 个网站，那么网络蜘蛛(Web Spider)就可以用这个原理把互联网上所有的网页都抓取下来。<br/>网络蜘蛛实现的流程图如图：<br/><br/><a href="http://www.yuan-chuang.cc/attachment.php?fid=44" target="_blank"><img src="http://www.yuan-chuang.cc/attachment.php?fid=44" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/> <br/>那好我继续往下讲从图中所看的设计原理。<br/> <br/>三：网络蜘蛛实现的关键点<br/> <br/> 1.从上述流程图中我们可以看到，我们需要给定一个入口的URL，蜘蛛才开始工作。<br/> <br/>这里我们就需要几个队列，来保存不同状态的链 接。<br/> <br/>按照严格的分类，我们需要四个队列，即运行队列，等待队列，完成队列，异常队列，但针对具体情况，因为太多队列调度复杂 ，我们只用了二个队列，等待队列跟运行队列合并成为运行队列，完成队列，由于我们只针对特定的网站，所以异常队列的必要性不 是太大。<br/> <br/>我们的线程一直从运行队列中读取最先写入队列的URL，如果存在，则往下执行，如果运行队列中没有数据了，则终止蜘蛛 的运行。<br/> <br/>每处理完一个URL，则把其写入完成队列，防止重复访问。同时对于每个页面上合法并过滤后的链接都会写入运行队列。<br/> <br/>对于一般的小程序，队列基本上用内存取存就可以了，但对于大型数据量而言，用内存保存数据肯定是不可取的，那么我们采取的是 用数据库模拟队列，即建了二个表，一为(RUNQUEUE)（运行队列），一为(SUCQUEUE)（完成队列）。<br/> <br/>两表的字段相同，包括，队列ID ，用来判断链接的顺序，为先进先出做依据，队列URL 即链接内容，队列深度，即该链接所处的深度，用来判断在多少层终止数据抓 取。同时写了两个方法，一为取得最先进入队列的数据，二为移除该数据。<br/> <br/>因此基本上模拟了队列的特征，可以进行海量数据的抓取 ，同时还可以进行断点续抓的功能。<br/> <br/>2 超<a href="http://www.lxysem.cn/post/461/" target="_blank">链接</a>的获取及处理<br/> <br/>对于任何网站的抓取，都少不了一个核心的东西，就是超链接，它是各个页面之间相互关联的钮带，也就是因为它，才把庞大的一个 互联网紧密的联系起来，使得各个页面之间不是孤立无助的。<br/> <br/>对于超链接的获取来说，还有一个比较重要的问题，就是对于一个网站有太多的链接了，有外部链接，内部链接，绝对链接，相对的 等等形式的，如果我们不做任何处理的保存下来，那么我想这个蜘蛛就会永无止境的跑下去了，却不一定能获取得我们想要的数据， 因此这是不可取的。对于此问题，我们需要提供几个解决方法：<br/> <br/>首先就是控制抓取层数，因为对于每一个链接，我们都给了它一个与之相对应的层数，如果这个层大于我们所给的层，那么就终止程 序；<br/> <br/>第二个方法就是过滤<a href="http://www.lxysem.cn/post/426/" target="_blank">关键字</a>，就是对链接中的字词进行分析，过滤掉一些关键字，或保留相关关键字，这里也有二种方法:<br/> <br/>第一就是只取得包含我们所给定的关键字的链接，比如说 (ITkafeiting) 我们只取得包含 (ITkafeiting) 这个词的链接，不包含的 我们就丢掉，这样所取的链接即为内部链接，并且这样的关键字是可以替加的，比如说我们要取得的链接中必须包含ITkafeiting 和 html 还是其它的都可以。<br/> <br/>第二种方法就是取得不包含我们所给定的关键字的链接，同时该关键字也是可替加的，这样一来，我们就很容易的对抓取链接进行筛 选，获得我们需要的链接。<br/> <br/>第三就是设置获取链接的个数，超过这个数字就终止；.<br/> <br/>第四就是设置运行时间，一旦到时间就终止。因此现在只是采取了第一和第二种方法，对于每个页面上的链接的获得的方法有二种， 第一种就是用正则表达式，但这种方法我个人觉得不是太好，如果链接的格式不同，或者javascript 中的链接就不一定能抓得下来 ；第二种方法，就是用JAVA自带的解释HTML 的包HTMLEditorKit，这种方法我觉得不会漏掉任何的链接，不管是相对的还是绝对的， 同时效率比用正则表达式高，因此，我们基本上是采用这种方式。<br/> <br/>对于链接的形式的不同，因为有相对的，绝对的，还有其它各种情况的，针对此问题，我特别写了一个方法，把所有的链接全部转换 成绝对的链接。这样那么就不会漏掉任何有用的数据。<br/> <br/>对于链接过滤主要涉及两个数组，第一个数组即是必须存在的关键字组，这一数组中，可以根据具体的网站页面链接情况进行配置， 同时其数组的个数是无限制的，分析链接时，链接中必须存在这个数组中所有的关键字，如果有任何一个不存在，则都会丢弃该链接 。<br/> <br/>如：该数组中有关键字，“http”, “ITkafeiting”, “html”,那么只有包含这些关键字的链接才有效，&nbsp;&nbsp;http://www.itkafeiting.com/index.html该链接则是有效的，而 http://www.itkafeiting.com/index.asp这样的链接则会被丢弃， 并且该数组一定要配置；第二个数组则为不需要存在的关键字组，这一数组中，也是根据具体的网站页面链接情况进行配置的，同时 其数组个数也是无限制的，分析链接时，链接中必须不存在这个数组中的任何一个关键字，如果有任何一个存在，则会丢弃该链接。<br/> <br/>如：该数组中有关键字，“asp”，那么 http://www.itkafeiting.com/index.asp则会被丢弃，该数组的配置是可选的，根据实际情 况可不配置，两个数组是同时使用的，进一步保证了链接的高过滤性。<br/> 21:01:14<br/>为了避免死循环，防止重复抓取页面，除了上述过滤链接外，还需要判断，我们需要入库的链接是否存在，因此需要把该链接与数据 库中的队列表中的数据进行判断（运行队列和完成队列都要判断），如存在则丢弃，不存在则写入运行队列。<br/><br/> <br/>通过上述方法，就可以很好的，很方便，很灵活的提取我们需要的相关链接进行处理，从而避免了太多无用链接的麻烦。 <br/> <br/>(呵呵讲到这里有点累了,还是坚持一下,我继续往下讲.下面说一下页面内容抓取.) <br/>通过从运行队列中取得的链接，则可以抓取该页面的所有源代码内容。这里主要应用到了 SUN 公司提供的NET 包。首先把链接先成&nbsp;&nbsp;URL 实例，通过HTTPConnection 方法打开该链接，然后获得其页面内容的信息流。<br/>再把该信息流转换成我们需要的字符串，这里面 有个问题是流只能应用一次，而在我们通过HTML 解析器获取其超链接的时候用的是流，因此没办法用二次流，经过思考先统一转成 字符串，然后在需要的时候，再把字符串转成流，从而达到我们的要求。<br/> <br/>4.如何解析HTML 内容<br/> <br/>当页面的内容抓取下来以后，那么接下来的事情就是解析 HTML 内容，并根据我们的需要提取相关的数据内容入库。<br/> <br/>因为每个网站的风格各异，页面格式也各异，因此想做成一个通用的能解析所有网页的程序是不太可能的，那么这一部分就是比较灵 活的，需要我们根据不同的网站，以及我们所需的不同的内容进行灵活方便的配置，或者做小部分改动即可应用就很不错了。<br/> <br/>因为 HTML 语言的特殊性，解析它是个非常麻烦的问题，通过比较发现采用正则表达式来分析HTML 是非常好的一种方式。因为在我 们的蜘蛛程序中，所有的解析都是采用正则表达式实现的。<br/>通过对很多网站的内容进行分析以后，我们发现，解析后形成的结果无非 就是四种情况，借用表的形式来说明比较直观，即，单行单列，单行多列，多行单列，多行多列，因此，我们针对这四种情况分析写 了四个不同的方法，返回不同的结果及类型，同时针对不同的页面，可能出现这四种类型的嵌套，循环等形式，需要根据实际情况来 定。<br/><br/>同时根据网站不同，所取数据的不同，需要写一个或多个正则表达式。对于正则表达式的解析，我们采用开源项目组里的一个正则表 达式包，功能比较强大。同时基本上与微软的正则表达式的规则区别不是太大，因此，使用起来更方便。<br/><br/>5.数据入库<br/> <br/>通过对页面内容的解析，就会提取到我们需要的数据，然后对数据进行优化，比如把全角转成半角，去掉其两边空格，<br/>或对一些日期等进行格式化以后，基本上就入库了。入库的时候还需要针对不同的字段进行判断，该记录是否存在，如存在，<br/>则放弃，尽可能提高入库数据的唯一性。<br/> <br/>6 线程的实现意义及方法<br/> <br/>对于网络蜘蛛而言，必须采用线程进行循环，因为这样可以提高效率，避免死循环，周期性运行而无需人工干预，易于<br/>控制，易于采用多线程等。<br/> <br/>当然采用线程也会有一些弊端，如网络阻塞的话，那么整个线程一直处于等待状态而导致死亡。<br/> <br/>那么这里我们采用了一种线程监控的方法，就是说有二个线程在运行，一个是主线程，另一个是监控线程，监控线程每隔一段时间就去访问主线种与其共享的变量，一旦发现超时，即认为网络阻塞，于时杀掉线程，重新启动该线程。<br/> <br/>避免了由于网络阻塞而线程一直等待的问题。<br/><br/>四:讲座结束语<br/><br/>以上的经验之谈纯属本人个人总结，希望能对一些朋友有所帮助。转载请完整保留此信息，如作修改，谢绝转载。我的讲座结束,谢谢大家支持。<a href="http://www.lxysem.cn" target="_blank">SEO公司</a> <a href="http://www.metedu.cn" target="_blank">在职博士</a><br/>
]]>
</description>
</item><item>
<link>http://www.yuan-chuang.cc/read.php/.htm#blogcomment</link>
<title><![CDATA[[评论] 小健讲座:搜索引擎与Web Spider原理详解]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.yuan-chuang.cc/read.php/.htm#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>