读书人

教你编纂简单的网络爬虫

发布时间: 2013-10-12 11:54:02 作者: rapoo

教你编写简单的网络爬虫

一、网络爬虫的基本知识

网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念。爬虫如何遍历网络呢,互联网可以看做是一张大图,每个页面看做其中的一个节点,页面的连接看做是有向边。图的遍历方式分为宽度遍历和深度遍历,但是深度遍历可能会在深度上过深的遍历或者陷入黑洞。所以,大多数爬虫不采用这种形式。另一方面,爬虫在按照宽度优先遍历的方式时候,会给待遍历的网页赋予一定优先级,这种叫做带偏好的遍历。实际的爬虫是从一系列的种子链接开始。种子链接是起始节点,种子页面的超链接指向的页面是子节点(中间节点),对于非html文档,如excel等,不能从中提取超链接,看做图的终端节点。整个遍历过程中维护一张visited表,记录哪些节点(链接)已经处理过了,跳过不作处理。使用宽度优先搜索策略,主要原因有:a、重要的网页一般离种子比较近,例如我们打开的新闻网站时候,往往是最热门的新闻,随着深入冲浪,网页的重要性越来越低。b、万维网实际深度最多达17层,但到达某个网页总存在一条很短路径,而宽度优先遍历可以最快的速度找到这个网页c、宽度优先有利于多爬虫合作抓取。二、网络爬虫的简单实现

1、定义已访问队列,待访问队列和爬取得URL的哈希表,包括出队列,入队列,判断队列是否空等操作

package webspider;import java.util.Set;public class MyCrawler {/** * 使用种子初始化 URL 队列 *  * @return * @param seeds *            种子URL */private void initCrawlerWithSeeds(String[] seeds) {for (int i = 0; i < seeds.length; i++)LinkQueue.addUnvisitedUrl(seeds[i]);}/** * 抓取过程 *  * @return * @param seeds */public void crawling(String[] seeds) { // 定义过滤器,提取以http://www.lietu.com开头的链接LinkFilter filter = new LinkFilter() {public boolean accept(String url) {if (url.startsWith("http://www.baidu.com"))return true;elsereturn false;}};// 初始化 URL 队列initCrawlerWithSeeds(seeds);// 循环条件:待抓取的链接不空且抓取的网页不多于1000while (!LinkQueue.unVisitedUrlsEmpty()&& LinkQueue.getVisitedUrlNum() <= 1000) {// 队头URL出队列String visitUrl = (String) LinkQueue.unVisitedUrlDeQueue();if (visitUrl == null)continue;DownLoadFile downLoader = new DownLoadFile();// 下载网页downLoader.downloadFile(visitUrl);// 该 url 放入到已访问的 URL 中LinkQueue.addVisitedUrl(visitUrl);// 提取出下载网页中的 URLSet<String> links = HtmlParserTool.extracLinks(visitUrl, filter);// 新的未访问的 URL 入队for (String link : links) {LinkQueue.addUnvisitedUrl(link);}}}// main 方法入口public static void main(String[] args) {MyCrawler crawler = new MyCrawler();crawler.crawling(new String[] { "http://www.baidu.com" });}}

至此,可以看到f:\spider文件夹下面已经出现了很多html文件,都是关于百度的,以“www.baidu.com”为开头。











读书人网 >编程

热点推荐