文章引用鸿扬大大的链接具体介绍怎样使用Jsoup包抓取HTML数据,是一个纯javaproject,并将其打包成jar包。希望了解怎样用java语言爬虫网页的能够看下。
杂家前文就又介绍用HTTP訪问百度主页得到html的string字符串,但html的文本数据假设不经过处理就是个文本字符串没有不论什么效果的。
所谓的浏览器就是负责将文本的html“翻译”成看到的界面。在前文有介绍,这个csdn的clientapp分首页、业界、移动、研发、程序猿、云计算五大类。
以业界为例。http://news.csdn.net/ 实际加上page1的http地址是:http://news.csdn.net/news/1
从上图可知,一个完整的新闻包括东西还是比較多的。将其抽象出来ID号、标题、链接、日期、图片链接、内容、类型。这7个属性。
一、新建org.yanzi.bean包,里面有两个java文件
NewsItem.java是上面具有7个属性的新闻bean
package org.yanzi.bean;
public class NewsItem
{
private int id;
/**
* 标题
*/
private String title;
/**
* 链接
*/
private String link;
/**
* 公布日期
*/
private String date;
/**
* 图片的链接
*/
private String imgLink;
/**
* 内容
*/
private String content;
/**
* 类型
*
*/
private int newsType;
public int getNewsType()
{
return newsType;
}
public void setNewsType(int newsType)
{
this.newsType = newsType;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getLink()
{
return link;
}
public void setLink(String link)
{
this.link = link;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getDate()
{
return date;
}
public void setDate(String date)
{
this.date = date;
}
public String getImgLink()
{
return imgLink;
}
public void setImgLink(String imgLink)
{
this.imgLink = imgLink;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
@Override
public String toString()
{
return "NewsItem [id=" + id + ", title=" + title + ", link=" + link + ", date=" + date + ", imgLink=" + imgLink
+ ", content=" + content + ", newsType=" + newsType + "]";
}
}
CommonException.java 这个主要是抛出异常。方便构造
package org.yanzi.bean;
public class CommonException extends Exception
{
/**
*
*/
private static final long serialVersionUID = 1L;
public CommonException()
{
super();
// TODO Auto-generated constructor stub
}
public CommonException(String message, Throwable cause)
{
super(message, cause);
// TODO Auto-generated constructor stub
}
public CommonException(String message)
{
super(message);
// TODO Auto-generated constructor stub
}
public CommonException(Throwable cause)
{
super(cause);
// TODO Auto-generated constructor stub
}
}
二、新建org.yanzi.csdn包,这里放三个java文件
Constant.java 这块将其弄成interface比較奇怪哈,写成class也ok
package org.yanzi.csdn;
public interface Constant
{
public static final int NEWS_TYPE_YEJIE = 1; //业界
public static final int NEWS_TYPE_YIDONG = 2; //移动
public static final int NEWS_TYPE_YANFA = 3; //研发
public static final int NEWS_TYPE_CHENGXUYUAN = 4;//程序猿
public static final int NEWS_TYPE_YUNJISUAN = 5; //云计算
}
URLUtil.java 这个负责获取到每个大类新闻的精确的url地址
package org.yanzi.csdn;
public class URLUtil
{
public static final String NEWS_LIST_URL = "http://www.csdn.net/headlines.html";
public static final String NEWS_LIST_URL_YIDONG = "http://mobile.csdn.net/mobile";
public static final String NEWS_LIST_URL_YANFA = "http://sd.csdn.net/sd";
public static final String NEWS_LIST_URL_YUNJISUAN = "http://cloud.csdn.net/cloud";
public static final String NEWS_LIST_URL_ZAZHI = "http://programmer.csdn.net/programmer";
public static final String NEWS_LIST_URL_YEJIE = "http://news.csdn.net/news";
/**
* 依据文章类型,和当前页码生成url
* @param newsType
* @param currentPage
* @return
*/
public static String generateUrl(int newsType, int currentPage)
{
currentPage = currentPage > 0 ? currentPage : 1;
String urlStr = "";
switch (newsType)
{
case Constant.NEWS_TYPE_YEJIE:
urlStr = NEWS_LIST_URL_YEJIE;
break;
case Constant.NEWS_TYPE_YANFA:
urlStr = NEWS_LIST_URL_YANFA;
break;
case Constant.NEWS_TYPE_CHENGXUYUAN:
urlStr = NEWS_LIST_URL_ZAZHI;
break;
case Constant.NEWS_TYPE_YUNJISUAN:
urlStr = NEWS_LIST_URL_YUNJISUAN;
break;
default:
urlStr = NEWS_LIST_URL_YIDONG;
break;
}
urlStr += "/" + currentPage;
return urlStr;
}
}
DataUtil.java 利用HttpURLConnection 利用get方式获取html的文本。也就是string类型的数据. 注意这个文件跟上个文件封装上的松耦合性。
package org.yanzi.csdn;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.yanzi.bean.CommonException;
public class DataUtil {
/**
* 获取HTML数据
* @param urlStr url地址
* @return
* @throws CommonException
*/
public static String doGet(String urlStr) throws CommonException{
StringBuffer sb = new StringBuffer();
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setDoInput(true);
conn.setDoOutput(true);
if(conn.getResponseCode() == 200){
InputStream is = conn.getInputStream();
int len = 0;
byte[] buf = new byte[1024];
while((len = is.read(buf)) != -1){
sb.append(new String(buf, 0, len, "UTF-8"));
}
is.close();
}else{
throw new CommonException("訪问网络失败00");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new CommonException("訪问网络失败11");
}
return sb.toString();
}
}
三、包名org.yanzi.biz,其下仅仅有这个类,复杂完毕真正的爬虫工作,即从html string字符串里提取出相应的新闻属性,存到新闻bean里
package org.yanzi.biz;
import java.util.ArrayList;
import java.util.List;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.yanzi.bean.CommonException;
import org.yanzi.bean.NewsItem;
import org.yanzi.csdn.DataUtil;
import org.yanzi.csdn.URLUtil;
/**
* 处理NewItem的业务类
* @author zhy
*
*/
public class NewsItemBiz
{
/**
* 业界、移动、云计算
*
* @param htmlStr
* @return
* @throws CommonException
*/
public List getNewsItems( int newsType , int currentPage) throws CommonException
{
String urlStr = URLUtil.generateUrl(newsType, currentPage);
String htmlStr = DataUtil.doGet(urlStr);
List newsItems = new ArrayList();
NewsItem newsItem = null;
Document doc = Jsoup.parse(htmlStr);
Elements units = doc.getElementsByClass("unit");
for (int i = 0; i < units.size(); i++)
{
newsItem = new NewsItem();
newsItem.setNewsType(newsType);
Element unit_ele = units.get(i);
Element h1_ele = unit_ele.getElementsByTag("h1").get(0);
Element h1_a_ele = h1_ele.child(0);
String title = h1_a_ele.text();
String href = h1_a_ele.attr("href");
newsItem.setLink(href);
newsItem.setTitle(title);
Element h4_ele = unit_ele.getElementsByTag("h4").get(0);
Element ago_ele = h4_ele.getElementsByClass("ago").get(0);
String date = ago_ele.text();
newsItem.setDate(date);
Element dl_ele = unit_ele.getElementsByTag("dl").get(0);// dl
Element dt_ele = dl_ele.child(0);// dt
try
{// 可能没有图片
Element img_ele = dt_ele.child(0);
String imgLink = img_ele.child(0).attr("src");
newsItem.setImgLink(imgLink);
} catch (IndexOutOfBoundsException e)
{
}
Element content_ele = dl_ele.child(1);// dd
String content = content_ele.text();
newsItem.setContent(content);
newsItems.add(newsItem);
}
return newsItems;
}
}
注意这个文件是真正的爬虫的核心,说明例如以下:
1、要爬虫一个html数据在之前能够使用HtmlParser。见链接http://www.cnblogs.com/loveyakamoz/archive/2011/07/27/2118937.html 但自从jsoup诞生后,使用比HtmlParser更方面。此处就是利用jsoup解析html的,须要载入lib目录下的jsoup-1.7.2.jar、jsoup-1.7.2-sources.jar。自己add to build path就可以。后者是源代码。能够查看,真正的包就第一个。
2、jsoup能够直接打开一个网页url,此处为了方便已经写了从url获取string类型的html代码了。
所以能够直接利用Document doc = Jsoup.parse(htmlStr); 得到Document类。
以业界新闻为例。http://news.csdn.net/news/1,按快捷键ctrl+u查看其源代码。搜索keywordunit能够看到:
每个新闻就是以keyword“unit”来标识的,第一页一共同拥有10条新闻所以有10个unit。Elements units = doc.getElementsByClass("unit"); 得到这10个新闻item的集合。
3、接下来就是对一个新闻提取具体信息了
先来看当中一个完整的新闻html代码:
微视、美拍等的春天,不是短视频应用的春天
发表于2014-07-25 16:52|690次阅读|6条评论
从html代码上能够看到,新闻的标题是以标识的。所以用Element h1_ele = unit_ele.getElementsByTag("h1").get(0);得到一个Element。此处get(0),是由于h1标签的就有1个。
h1标识里的代码是:
href="http://www.csdn.net/article/2014-07-30/2820930" target="_blank" >IDC:全球智能机出货量涨23% 华为进前5且翻番
所以通过 Element h1_a_ele = h1_ele.child(0);
String title = h1_a_ele.text();
String href = h1_a_ele.attr("href");
String title = h1_a_ele.text();
String href = h1_a_ele.attr("href");
得到标题和链接。
接下来通过h4的tag找日期:
发表于class="ago">14小时前|class="view_time">2944次阅读|class="num_recom">17条评论
通过class找到ago孩子。最终得到时间。
其它的都相似了,从中能够看出假设是依据html外围的标签,用getElementsByTag("h1").get(0)。假设里面包括的有class则要用getElementsByClass("ago").get(0)来进一步定位。假设没有class,仅仅是普通的孩子,利用child(0)定位得到Element。
最后是測试代码:
Test.java
package org.yanzi.test;
import java.util.List;
import org.yanzi.bean.CommonException;
import org.yanzi.bean.NewsItem;
import org.yanzi.biz.NewsItemBiz;
import org.yanzi.csdn.Constant;
public class Test
{
public static void main(String[] args){
Test test = new Test();
test.test01();
}
@org.junit.Test
public void test01()
{
NewsItemBiz biz = new NewsItemBiz();
int currentPage = 1;
try
{
/**
* 业界
*/
System.out.println("-----------业界-----------");
List newsItems = biz.getNewsItems(Constant.NEWS_TYPE_YEJIE, currentPage);
for (NewsItem item : newsItems)
{
System.out.println(item);
}
/**
* 程序猿杂志
*/
System.out.println("-----------程序猿-----------");
newsItems = biz.getNewsItems(Constant.NEWS_TYPE_CHENGXUYUAN, currentPage);
for (NewsItem item : newsItems)
{
System.out.println(item);
}
/**
* 研发
*/
System.out.println("-----------研发-----------");
newsItems = biz.getNewsItems(Constant.NEWS_TYPE_YANFA, currentPage);
for (NewsItem item : newsItems)
{
System.out.println(item);
}
/**
* 移动
*/
System.out.println("-------------移动---------");
newsItems = biz.getNewsItems(Constant.NEWS_TYPE_YIDONG, currentPage);
for (NewsItem item : newsItems)
{
System.out.println(item);
}
System.out.println("-------------结束---------");
} catch (CommonException e)
{
e.printStackTrace();
}
}
}
执行结果:
-----------业界-----------
NewsItem [id=0, title=IDC:全球智能机出货量涨23% 华为进前5且翻番, link=http://www.csdn.net/article/2014-07-30/2820930, date=15小时前, imgLink=http://cms.csdnimg.cn/article/201407/30/53d844474e279.jpg, content=IDC日前公布了2014年第二季度全球智能手机市场相关的研究数据。数据显示,位居全球智???
手机出货量前五的厂商各自是三星、苹果、华为、联想和LG。华为智能手机出货量更是同比大涨了近一倍,而三星却同比下降。, newsType=1] NewsItem [id=0, title=专訪叶劲峰:漫谈游戏开发和游戏优化, link=http://www.csdn.net/article/2014-07-30/2820931, date=15小时前, imgLink=http://cms.csdnimg.cn/article/201407/30/53d85983915fe.jpg, content=社区之星第50期採訪了腾讯互动娱乐研发部引擎技术中心专家project师叶劲峰,他讲述了译著《游戏引擎架构》经历。并就游戏引擎、优化、游戏开发学习等进行了分享。
与此同一时候,叶劲峰也将坐镇社区问答第8期回答大家问题。, newsType=1] NewsItem [id=0, title=修成正果:Mozilla正式任命Chris Beard为CEO, link=http://www.csdn.net/article/2014-07-29/2820918, date=2014-07-29 14:40, imgLink=http://cms.csdnimg.cn/article/201407/29/53d712420edcd.jpg, content=Mozilla正式任命暂时CEO Chris Beard为正式CEO,其于2004年增加Mozilla。随后一直负责产品、营销、创新等方面的工作。后在风投公司担任高管。在创新和企业管理方面积累了非常多经验。Beard被公觉得最适合的CEO人选。, newsType=1] NewsItem [id=0, title=苹果和IBM成最佳搭档 微软谷歌或受威胁, link=http://www.csdn.net/article/2014-07-28/2820905-apple-ibm, date=2014-07-29 14:51, imgLink=http://cms.csdnimg.cn/article/201407/28/53d61d099020f.jpg, content=月中,苹果宣布与IBM达成独家合作协议。两家合作在非常大程度上是互补的,由于他们分别专注于消费者和企业市场,合作后必在企业级市场推出更强大的产品。同一时候,他们的发展也会对微软、谷歌和黑莓等公司带来不利影响。
, newsType=1] NewsItem [id=0, title=敢为人先:亚马逊推出3D定制和销售门户站点, link=http://www.csdn.net/article/2014-07-29/2820911, date=2014-07-29 08:21, imgLink=http://cms.csdnimg.cn/article/201407/29/53d6e919d6e7e.jpg, content=在线零售商亚马逊近日推出了一门户站点,该站点是一个3D打印产品的销售平台。用户能够依据自己的喜好,比方材料、大小、样式和颜色的个性化。来定制和购买3D产品。甚至仅仅要喜欢,还能够将照片或喜好的话定制上去。, newsType=1] NewsItem [id=0, title=微软中国遭工商总局调查 或因涉及“不公平交易”, link=http://www.csdn.net/article/2014-07-29/2820910, date=2014-07-29 07:47, imgLink=http://cms.csdnimg.cn/article/201407/29/53d6dcefe99e0.jpg, content=日前。国家工商总局相关人员突訪了微软位?
?我国北京、上海、广州和成都四地的办公室,正就一些事情展开问询。或因该公司涉及操作系统垄断问题和贿赂官员以换取软件合同等。
, newsType=1] NewsItem [id=0, title=传智播客“2014年全国高校IT骨干教师研修班”火热开班, link=http://www.csdn.net/article/2014-07-28/2820886, date=2014-07-28 10:11, imgLink=http://cms.csdnimg.cn/article/201407/28/53d5b05190e1a_thumb.jpg, content=日前,由传智播客主办的“2014年全国高校IT骨干教师研修班”火热开班。
本届研修班吸引了来自全国30多所院校,近60名IT类专业教师參加。接下来将分Android、Java、PHP、网页平面UI、.Net共5个班开展课程学习交流。
, newsType=1] NewsItem [id=0, title=【畅言】从程序猿到架构师的方法与逻辑, link=http://www.csdn.net/article/2014-07-28/2820883, date=2014-07-28 08:51, imgLink=http://cms.csdnimg.cn/article/201407/28/53d59d5f7d4ca.jpg, content=架构师这个词常常见到,非常多人都冠着这个头衔。实际上非常多人对架构师究竟是干什么的都没有统一的认识。V众投发起人李智勇则利用特定场景进行分析。诠释了架构师这个概念,并给出怎样成为架构师方法。, newsType=1] NewsItem [id=0, title=Windows Phone 8.1 Update 1:图标可合并成目录、4G语音通话, link=http://www.csdn.net/article/2014-07-28/2820882, date=2014-07-28 07:52, imgLink=http://cms.csdnimg.cn/article/201407/28/53d58fc0ef514.jpg, content=微软最终计划公布已经进入RTM阶段的Windows Phone 8.1Update 1(或GDR1),可能包括:对图标进行拖拽以及合并成目录、支持1280 x 800屏幕分辨率和7英寸的设备、支持交互式的手机外壳(见上图),以及4G语音通话。, newsType=1] NewsItem [id=0, title=智能硬件生态未成。打造平台为时尚早, link=http://www.csdn.net/article/2014-07-28/2820881, date=2014-07-28 00:37, imgLink=null, content=当前的智能硬件产业发展是由创业公司探路。巨头纷纷跟进打造开放平台。
但智能硬件市场至今无标杆性产品、开发人员及应用前景不明、尚未找到用户“痛点”等特征表明市场仍处于萌芽阶段,打造平台为时尚早。, newsType=1] -----------程序猿----------- NewsItem [id=0, title=Server SAN:云计算时代的弄潮儿, link=http://www.csdn.net/article/2014-07-28/2820902, date=2014-07-28 15:17, imgLink=http://cms.csdnimg.cn/article/201407/28/53d6087c3920e.jpg, content=Server SAN为何一时间能成为了高大上的东西?分布式存储说来并不新鲜。2000年诸如GPFS、Lustre、Panasas及PVFS就出现了。但之后发展不温不火。
说究竟还是实际应用需求的推动,当前的繁荣源于数据在爆炸式增长。, newsType=4] NewsItem [id=0, title=大数据 “在路上”, link=http://www.csdn.net/article/2014-07-25/2820859, date=2014-07-25 11:03, imgLink=http://cms.csdnimg.cn/article/201407/25/53d1cfb8a3844.jpg, content=未来的Google无人驾驶汽车,一定像是一个移动的数据中心,须要同一时候处理着结构化、非结构化的大量数据。彼时的Big Data才算是真正用于汽车。, newsType=4] NewsItem [id=0, title=融合与统一:简评OS X10.10 Yosemite, link=http://www.csdn.net/article/2014-07-21/2820768, date=2014-07-21 17:09, imgLink=http://cms.csdnimg.cn/article/201407/23/53cf2e9689263.jpg, content=苹果旗下两大系列操作系统OS X和iOS发展步调并不一致。相对于iOS的迅猛发展。OS X显得不温不火。Yosemite的公布,应该说是个里程碑。本文基于Yosemite-Developer Preview 1.0版本号简单介???这个OS X家族的新成员。
, newsType=4] NewsItem [id=0, title=智能家居产品安全漫谈, link=http://www.csdn.net/article/2014-07-21/2820748, date=2014-07-21 11:06, imgLink=http://cms.csdnimg.cn/article/201407/21/53cc8931b917b.jpg, content=移动互联网技术的广泛应用为智能家居产业的发展提供了必要条件,不管传统巨头还是新兴创业公司都在投入这一领域。但随之而来的安全问题却未引起足够重视。, newsType=4] NewsItem [id=0, title=可穿戴计算机改变信息交互方式, link=http://www.csdn.net/article/2014-07-18/2820718, date=2014-07-18 09:51, imgLink=http://cms.csdnimg.cn/article/201407/18/53c8bf81c4723.jpg, content=可穿戴设备帮助我们更方便地感觉和捕捉世界。并且,我们也在以新的方式进行感官交流。
未来几十年。可穿戴计算机将嵌入我们的衣服、珠宝甚至皮肤。而这将对人类信息交互方式产生非常大影响。
, newsType=4] NewsItem [id=0, title=高效能技术团队的协同工具箱, link=http://www.csdn.net/article/2014-07-16/2820681, date=2014-07-16 13:30, imgLink=http://cms.csdnimg.cn/article/201407/16/53c6483a059be.jpg, content=使用适合团队的协同工具。不但能使工作按预定成本如期顺利推进,并且能实现对团队成员、项目过程以及产品等的分析管理。未经调研就选择别人觉得好的工具。非常可能遭遇“水土不服”。, newsType=4] NewsItem [id=0, title=当虚拟照进现实——Oculus的世界梦, link=http://www.csdn.net/article/2014-07-14/2820639, date=2014-07-14 13:19, imgLink=http://cms.csdnimg.cn/article/201407/14/53c36d0be8cd1.jpg, content=专注虚拟现实设备研发的Oculus被Facebook以20亿美元收于麾下,Oculus公司创始人Palmer Luckey希望建立自己的虚拟现实硬件生产线,他还表示要从用户的角度来不断完好Rift,未来是属于用户的,而不仅仅是Oculus。, newsType=4] NewsItem [id=0, title=在动态网络下实现分布式共享存储, link=http://www.csdn.net/article/2014-07-09/2820585-implementing-distributed-shared-memory-for-dynamic-networks, date=2014-07-09 10:59, imgLink=http://cms.csdnimg.cn/article/201407/09/53bcddd2580b0.jpg, content=本文介绍了分布式环境下实现共享内存模型会遇到的各种问题和挑战。并针对不同问题介绍多种算法的优劣性。
本文是对现阶段该领域研究现状的整体介绍,通过本文能了解动态分布式共享内存研究的前沿状况、挑战与机遇。
, newsType=4] NewsItem [id=0, title=从Objective-C到Swift, link=http://www.csdn.net/article/2014-07-08/2820568, date=2014-07-08 11:22, imgLink=http://cms.csdnimg.cn/article/201407/09/53bcabb118d79.jpg, content=2014年WWDC大会。苹果在毫无预兆的情况下公布了Swift语言。Swift背后的概念大多与Objective-C相似,但更为简洁、自然,也吸收了非常多其它语言的语法。本文将对Swift的语法、特点及改进进行全面介绍。, newsType=4] NewsItem [id=0, title=50年内有望实现的7大技术, link=http://www.csdn.net/article/2014-07-07/2820549, date=2014-07-07 10:43, imgLink=http://cms.csdnimg.cn/article/201407/07/53ba0dedb7494.jpg, content=1964年,美国电气与电子project学会IEEE杂志《IEEE Spectrum》刚成立时,一些预想家就曾预測过50年后的科技走势,现在,这一切都发生了。
现在又有一批预想家预測了未来50年的科技发展趋势。, newsType=4] -----------研发-----------
最后通过Export---Java---JAR file将其打包。
附个jsoup的相关链接:http://blog.csdn.net/yjflinchong/article/details/7743995
源代码下载链接:http://download.csdn.net/detail/yanzi1225627/7697313
版权声明:本文博主原创文章。博客,未经同意不得转载。