网络采集器Demo:Jsoup+Java多线程实现[爬虫](上)
2015-11-01 00:01
274 查看
ailab-mltk:/article/8137889.html
里面最简单,但是很常用的一个部分,就是网络爬虫,从网页上获取文本信息
这里用到两个工具,一个就是Java多线程(基于Java5 以上的线程池模式,区别于过时的Runable),另外一个是一个小工具:Jsoup,用于解析html网页,获取其中的内容,关于Jsoup的使用,这是一个技术活,在下面的描述中会介绍一些基础操作,但主要还是需要师弟们自己去学习:http://www.open-open.com/jsoup/。
demo的功能是,爬取新浪主页的新闻文本内容。
下面我们一步一步来:
新浪首页即是我们的种子页面,首先我们需要获取新浪首页上的全部内容链接
1.用Jsoup获得种子页面的html代码
返回的是Jsoup中的Docment对象,内包含html代码以及其结构信息,它可以用作我们进一步对获取的html代码分析。
2.获得种子页面上的全部有效链接
getAllUrl返回的是种子页面上全部锚链接的集合,注意这个集合用的是HashSet,可以自动排除重复的链接,可以自己设计一个ExactLinks类,需要重写hashCode和equals函数。但是,到这一步并没有结束,filterUrl方法是为了过滤无用的链接,CrawlUnitParam.SINA_URL_MODEL中存储的是有用链接的模式集合,可以自己设计,匹配成功才加入最终的集合,并返回。我的模式集合是:
3.解析获得每个链接中的文本内容
我们将上面的每个链接传入函数getParagraphContent,返回该页中有效的文本内容
下面循环中的text方法是获得html代码子块中包含的文本信息,对所有这样的文本信息进行拼接,返回。
好了,经过以上的步骤,相信师弟们自己完成一个串行的采集器没有问题了吧,但是我并没有那样实现,下一节将描述一个并行实现的采集器,这样我们会获得更高的效率。
里面最简单,但是很常用的一个部分,就是网络爬虫,从网页上获取文本信息
这里用到两个工具,一个就是Java多线程(基于Java5 以上的线程池模式,区别于过时的Runable),另外一个是一个小工具:Jsoup,用于解析html网页,获取其中的内容,关于Jsoup的使用,这是一个技术活,在下面的描述中会介绍一些基础操作,但主要还是需要师弟们自己去学习:http://www.open-open.com/jsoup/。
demo的功能是,爬取新浪主页的新闻文本内容。
下面我们一步一步来:
新浪首页即是我们的种子页面,首先我们需要获取新浪首页上的全部内容链接
1.用Jsoup获得种子页面的html代码
public class JsoupGetDocument { public static Document getDocumentByJsoupBasic(String url) { try { // 设置连接超时和读数超时 // 设置忽略过期页面 return Jsoup.connect(url).timeout(120000).ignoreHttpErrors(true) .ignoreContentType(true).get(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }第7行解释:链接到要获取html代码的url,设置等待时间,忽略http错误,忽略网页内容编码格式
返回的是Jsoup中的Docment对象,内包含html代码以及其结构信息,它可以用作我们进一步对获取的html代码分析。
2.获得种子页面上的全部有效链接
public class FetchLinksFromPage { // 获得所有的链接 public Set<ExactLinks> getAllUrl(String seedUrl) { Set<ExactLinks> urlSet = new HashSet<ExactLinks>(); try { Document docPage = JsoupGetDocument .getDocumentByJsoupBasic(seedUrl); Elements eleLinks = docPage.select("a[href]"); for (Element eleLink : eleLinks) { String url = eleLink.attr("abs:href"); String urlMD5 = new TransMD5().getMD5Code(url); urlSet.add(new ExactLinks(url, urlMD5)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return urlSet; } // 过滤出有用的url public Set<ExactLinks> filterUrl(String seedUrl) { Set<ExactLinks> urlSet = this.getAllUrl(seedUrl); Set<ExactLinks> filterLinks = new HashSet<ExactLinks>(); for (String urlModel : CrawlUnitParam.SINA_URL_MODEL) { for (ExactLinks links : urlSet) { if (links.getUrl().contains(urlModel)) { filterLinks.add(links); } } } return filterLinks; } }第8行获得页面Docment对象后,第10行获得全部带有链接信息的元素块,这里Elements对象是一个集合,其中每一个Element都是单独一个含有链接的html子块,这里要注意,select方法是Jsoup精髓,传入的参数是一个匹配html代码位置的模式串,关于这个模式串的设计,就是之前说的技术活,学习:http://www.open-open.com/jsoup/selector-syntax.htm。下面的循环是对每个子块中的链接元素进行提取,并加入结果集合。
getAllUrl返回的是种子页面上全部锚链接的集合,注意这个集合用的是HashSet,可以自动排除重复的链接,可以自己设计一个ExactLinks类,需要重写hashCode和equals函数。但是,到这一步并没有结束,filterUrl方法是为了过滤无用的链接,CrawlUnitParam.SINA_URL_MODEL中存储的是有用链接的模式集合,可以自己设计,匹配成功才加入最终的集合,并返回。我的模式集合是:
public class CrawlUnitParam { public static List<String> SINA_URL_MODEL = new ArrayList<String>(); static { SINA_URL_MODEL.add(".shtml"); SINA_URL_MODEL.add(".html"); } }可以自己打印一下解析出来的全部链接。
3.解析获得每个链接中的文本内容
我们将上面的每个链接传入函数getParagraphContent,返回该页中有效的文本内容
public class FetchPaContentFromPage { public String getParagraphContent(String pageUrl) { String paragraphContent = ""; try { Document docPage = JsoupGetDocument .getDocumentByJsoupBasic(pageUrl); Elements eleParagraphs = docPage.select("p"); for (Element eleParagraph : eleParagraphs) { String content = eleParagraph.text(); paragraphContent += content; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } return paragraphContent; } }同样在第8行获得页面的Docment对象之后,下面就是对包含有效文本的html子块进行抽取,还是使用select方法,至于什么是有效的文本信息,这些内容包含在具有什么特点的html子块中,需要我们分析网站页面的html代码,新浪新闻的有效信息就包含在<p></p>子块中,于是我们如上进行抽取。
下面循环中的text方法是获得html代码子块中包含的文本信息,对所有这样的文本信息进行拼接,返回。
好了,经过以上的步骤,相信师弟们自己完成一个串行的采集器没有问题了吧,但是我并没有那样实现,下一节将描述一个并行实现的采集器,这样我们会获得更高的效率。
相关文章推荐
- winpcap实现从TCP三次握手到发送http请求
- TCP中用到的定时器
- 基于ARP和WinPcap的网络嗅探
- 简述VM虚拟机网络设置
- 一起来玩树莓派(1)--网络环境配置篇
- Android imageloader加载网络,本地图片方式
- Http
- [Django与表单]先来了解HttpRequest对象
- HTTP协议详解之响应篇
- HTTP报文01
- 【Writeup】第六季极客大挑战(部分题目)
- http 文件头详解
- 用 WinPcap 获取网络接口列表
- TCP/IP详解 卷1 笔记 第11章 UDP:用户数据报协议
- 神经网络Tips 和Tricks
- 二:理解ASP.NET的运行机制(例:基于HttpHandler的URL重写)
- 一:理解ASP.NET的运行机制(例:通过HttpModule来计算页面执行时间)
- iOS中 UIWebView加载网络数据 技术分享
- iOS中 UIWebView加载网络数据 技术分享
- 关于为何《优酷视频使用http协议,而不是使用Rtmp协议呢》的回答