Home >Web Front-end >HTML Tutorial >网页爬虫系统的设计_html/css_WEB-ITnose
网络爬虫,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。当你需要大量的网络数据的时候,比如需要做一些数据分析,需要学习一些基于内容处理的算法的时候,爬虫程序就可以来为你抓取网站上的数据,人工一个页面一个页面的查找复制肯定不是办法,这个时候就需要编写爬虫来自动的为你去抓取网页数据。这篇博客将会讲述网页爬虫的设计。
前些天有一个需求就是从大众点评网站上抓取一点店铺数据作为推荐算法学习的数据,需要设计一个爬虫来为我获取这些店铺数据。根据要求,这个爬虫要在一个大众点评的根据地标进行店铺分类的页面获取地标的url,之后根据这些url抓取店铺的列表,之后根据列表来获取店铺的详情。
一般网页爬虫系统架构主要需要考虑以下方面
以上就是一个爬虫需要考虑的最简单的部分。接下来会谈论一下实现的细节,大众点评的爬虫我是用Java编写的所以在这里我将主要使用Java语言表述。
这两个部分可以放在一块,因为Java中可以直接请求道网页的源代码而不用下载到本地的磁盘中,关于解析器:我推荐使用Jsoup。Jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。Jsoup的主要功能如下:
比如我想解析下面这个网页的店铺名称
可以打开浏览器的开发者工具,分析出来店铺名称在main标签下有一个id为basic-info的标签,这个标签中有一个shop-name标签,这个标签的内容就是店铺名称。当然有的地方不好分析的也要用到正则表达式来分析字段。
在Jsoup的帮助下只要几行代码就能解决:
Document doc = Jsoup.connect(requestUrl). header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0").get();Element basicBody = doc.getElementById("basic-info");String shopName = basicBody.getElementsByClass("shop-name").get(0).childNode(0).toString().trim();System.out.println(shopName);
注意header一定要设置,不然的话有的网站是会因为没有完整的头信息直接403拒绝访问爬虫的请求的。
以上就是一些细节,接下来来讨论下可能会遇到的问题:
网站403拒绝访问:
现在的网站肯定都为了防止爬虫系统抓取他们的数据而做了处理,如果爬虫在短时间内访问了网站的大量连接,对方的服务器会发现,并且封掉你的IP,这时候你只会收到403拒绝访问,可能在30分钟或一段时间之后爬虫才能恢复对网站的访问。这个时候可以让爬虫休息一段时间在进行工作,Java的异常处理机制为我们提供了便利,我们可以通过异常捕获的方法来得知403错误,通过捕获一个HttpStatusException来分析是否是被对方服务器发现而拒绝访问。从而暂停爬虫的工作,当然也可以在捕获这个异常之后通过一段代码来更换代理IP,如果有大量IP的话。
try{ //连接并解析Html}catch (HttpStatusException e){//异常捕获 if (e.getStatusCode()==403){ try { logUtil.writeToHttpStatesException(); //日志写入 System.out.println("HttpStatusException! Program will sleep for "+configuration.forbiddenSleepTime/1000/60+"min."); Thread.sleep(configuration.forbiddenSleepTime); //进程休眠 } catch (InterruptedException e1) { e1.printStackTrace(); } } }
这个时候日志系统的用途就体现出来了,日志系统无形中提升了爬虫的稳定性,在抓取的时候可能会遇到各种异常,Socket超时,Http状态错误,数组越界,空指针等等,如果爬虫因为未知的错误而停止了运行,因为短期开发的过程中不可能想到所有可能出现的错误情况,第二次爬虫重新启动之后可以读取日志,这样就不会因为一个崩溃错误而导致爬虫把抓取过的信息再抓取一遍了。
以下是我设计的爬虫系统的结构:
因为我的爬虫需要抓取三种不同的网页,所以我设计了一个CrawlerManager类来管理调度不同类型的爬虫,这个Manager使得整个爬虫系统更加易于维护和调整,并且使得整个程序的逻辑结构更加清楚;
之后就可以开始抓取啦~