网络爬虫-使用java语言抓取网络数据
前提:熟悉java语法(能看懂就行)
- 准备阶段:从网页中获取html代码
- 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件
上一片文章已经介绍我们可以使用两个方式来抓取网络数据实现网络爬虫,并且大致介绍了一下怎么使用正则表达式去实现数据的抓取
由于笔者曾经学过一段时间java和android相关的技术,今天就讲讲怎么使用java去抓取网络数据,关于Python有机会等笔者好好研究一下再来分享,但其实会一种就可以,除非你的需求非常强大或者是在想装逼。
一:准备阶段--》获取html代码
1:打开你对应想要获取数据的网页,使用firefox打开(因为他有一个自带的神器叫:firebug,关于firebug这里就多说了,反正对于网页开发来说她就是神器),这里我们使用的是dota首页英雄的介绍。
首先来看看我们需要的数据
2:由于在网页开发中也是分模块开发的,所以一定的区域在html中对应对应的html代码模块,所以我们选取界面中一个小的模块作为练习。
找到对应的模块,点击右键在firebug中查看元素
(确保已安装firebug,没有安装的去火狐工具栏中工具标签里面的一个附加组件搜索并下载安装就可以)
这个时候网页的下面就会显示对应模块的html代码,我们需要找到我们想要获取的数据对应的html模块代码,点击右键拷贝我们需要的html。
3:在界面简一个html文件将拷贝好的html代码粘贴到文件中,然后就需要哪么一丢丢的html相关知识了,就是补充html中的数据,使他成为完整的html文件
这里注意一下编码方式:开发中常用的都是utf-8的格式
二:实战阶段--》抓取html(网页数据)
然后我们就要正式开工了,后面才是重点,前面那都是傻瓜是的操作(后面的才做中需要有那么一丢丢的java或者android开发的基础,当然不会耶没有关系,笔者会完整的介绍流程)
1:代开Eclipse
新建一个java项目,并且点击项目中的src新建一个class专门用来实现数据的解析
2:新建好项目之后就要用到我们的一个java的jar包,专门用来抓取网络数据的包:关于包的下载后面笔者会给出下载链接
将下载好的jar包导入到java工程项目中。
然后我们需要将他添加到build路径(这里是一个常识,java中的jar包没有添加到build路径是不能使用的,添加之后对应的咖啡图标会变成奶瓶)
成功之后的显示
下面开始使用java正式抓取并解析html(网页)数据
根据下面的图片在java工程项目中书写html数据解析的代码:(注意里面的步骤)
java核心代码:
try { //文件路径 String path = " /Users/icocos/Desktop/iCocos.html"; //加载网页 Document doc = Jsoup.parse(new File(path), "UTF-8"); //解析网页 Elements lis = doc.select("li"); 21 //遍历数组 for(int i = 0; i < eles.size(); i++) { //根据i获取对应的元素 Element li = lis.get(i); //取图片 Element img = li.select("img").get(0); // System.out.println(img.attr("src")); //获取图片名 String imgName = img.attr("src"); 45 Element p = li.select("p").get(0); String personName = p.text(); //打印数据 System.out.println(imgName + "," + personName); } } catch { //错误(异常)处理 e.printStackTrace(); }
此时点击Run运行之后,Eclipse就会根据你的代码输出对应的信息
但是这个时候我并不能直接使用数据所以需要在java代码中做一些相应的修改,使得输出的数据可以直接拷贝并且读到plist中,其实就是数组或者字典数据
我们知道在ios开发中从plist文件中读取数据时最常见的,当然你也可以使用其他方式,但是没有比这更简单了。
下面我给java代码做一些调整
1:在for循环之前输入这一行代码,实现数据拼接并且数据
- System.out.println("NSArray *apps = @[");
2:接着就需要在for循环结束之后输入预知对应的拼接数组结尾标志
- System.out.println("]");
3:在for循环内部的最后面我们需要在每次循环的时候都要使用上面的代码进行拼接并且使用逗号做相应的分割
- System.out.println("@{@\"name\":@\"" + personName + "\", @\"icon\":@\""+ imgName + "\"},");
最后完整的java获取并且解析html数据如下;
public class iCocos { public static void main (String[] args) { 5 try { //文件路径 String path = " /Users/icocos/Desktop/iCocos.html"; //加载网页 Document doc = Jsoup.parse(new File(path), "UTF-8"); //解析网页 Elements lis = doc.select("li"); System.out.println("NSArray *apps = @["); //遍历数组 for(int i = 0; i < eles.size(); i++) { //根据i获取对应的元素 Element li = lis.get(i); //取图片 Element img = li.select("img").get(0); // System.out.println(img.attr("src")); //获取图片名 String imgName = img.attr("src"); Element p = li.select("p").get(0); String personName = p.text(); //打印数据 // System.out.println(imgName + "," + personName); System.out.println("@{@\"name\":@\"" + personName + "\", @\"icon\":@\""+ imgName + "\"},"); } System.out.println("]"); } catch { //错误(异常)处理 e.printStackTrace(); } } }
这个时候回打印输出下面的代码,
下面我们就需要在xcode中做事情了,做什么事呢,就是将输出的以NSArray开头的所有数据在Xcode中转换为plist的数据,当然你也可以不转换,做少部分的修改之后直接使用JSON解析技术去解析,但是那样不是最好的办法。
在Xcode中新建一个项目工程,在ViewDidLoad中粘贴拷贝过来的代码,这个时候是不是看起来非常熟悉,对了,她就是我吗开发中常用到的数组数据。
下面我就使用循环遍历去讲NSArray数组数据写到plist文件中。
- (void)viewDidLoad { [super viewDidLoad]; NSArray *apps = @[ @{@"name":@"敌法师", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/dfss.jpg"}, @{@"name":@"火枪", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/arjj.jpg"}, @{@"name":@"德鲁伊", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/dlyy.jpg"}, @{@"name":@"月骑", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yzqs.jpg"}, @{@"name":@"变体精灵", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/btjl.jpg"}, @{@"name":@"娜迦海妖", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/njhy.gif"}, @{@"name":@"猴子", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/hycm.jpg"}, @{@"name":@"白虎", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yzjs.jpg"}, @{@"name":@"隐形刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yxck.jpg"}, @{@"name":@"巨魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/jmzj.jpg"}, @{@"name":@"直升机", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/arzs.jpg"}, @{@"name":@"赏金猎人", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Naka.gif"}, @{@"name":@"骷髅射手", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/KLSS.gif"}, @{@"name":@"育母蜘蛛", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YMZZ.gif"}, @{@"name":@"血魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/XM.gif"}, @{@"name":@"黑暗游侠", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Nbrn.gif"}, @{@"name":@"虚空假面", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/EC45.gif"}, @{@"name":@"蛇发女妖", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/H00V.gif"}, @{@"name":@"地卜师", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/H00I.gif"}, @{@"name":@"地穴刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/DXCK.gif"}, @{@"name":@"蚂蚁", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/DXBZ.gif"}, @{@"name":@"幻影刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/HYCK.gif"}, @{@"name":@"闪电幽魂", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/E002.gif"}, @{@"name":@"影魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YM01.gif"}, @{@"name":@"小鱼人", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yryx.gif"}, @{@"name":@"幽鬼", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YG1.gif"}, @{@"name":@"圣堂刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/E01Y.gif"}, @{@"name":@"灵魂守卫", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/LHSW.gif"}, @{@"name":@"熊战士", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Huth.gif"}, @{@"name":@"剧毒术士", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/JDSS.gif"}, @{@"name":@"冥界亚龙", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/MJYL.gif"}, @{@"name":@"复仇之魂", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Hvwd.jpg"}, @{@"name":@"剑圣", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/jsjs.jpg"} ]; [newApps writeToFile:@"/Users/icocos/Desktop/apps.plist" atomically:YES];
这个时候我吗的左面就有了这个plist文件,打开之后你会看到
最后的步骤就是图片的下载,
//简单写入
// for (NSDictionary *dict in apps) { // NSString *icon = dict[@"icon"]; // // // 新建网络图片的URL路径 // NSURL *url = [NSURL URLWithString:icon]; // // // 下载图片的二进制数据 // NSData *data = [NSData dataWithContentsOfURL:url]; // // // 截取文件名 // NSString *filename = [icon lastPathComponent]; // // // 文件路径 // NSString *iconPath = [NSString stringWithFormat:@"/Users/icocos/Desktop/Icons/%@", filename]; // // [data writeToFile:iconPath atomically:YES]; // }
//由于plist中图片名使用的都是对应链接的最后一个名字,所以我们不能使用上面的方法,还需要做一些处理,才能真正使用
NSMutableArray *newApps = [NSMutableArray array]; for (NSDictionary *dict in apps) { NSMutableDictionary *newDict = [NSMutableDictionary dictionary]; newDict[@"name"] = dict[@"name"]; newDict[@"icon"] = [dict[@"icon"] lastPathComponent]; [newApps addObject:newDict]; } [newApps writeToFile:@"/Users/icocos/Desktop/apps.plist" atomically:YES]; }
图片下载完成之后你会回看到对应的文件夹中快速的出现了好多的图片
此时我们就得到了一份和网页想相对应比较完整的plist数据,后面我们要做的就是将我们的plist数据显示到界面,后面我就不介绍了,详细请看:plist文件读取
最后总结一下,如果以后遇到了关于需要抓取网络数据实现网络爬虫的功能的时候,我们基本上想到的第一种方法就是使用java语言,当然公司一般不会有这样的要求,公司一般都是使用自己服务器的api来实现,特殊情况除外。
当然你也可以使用正则表达式或者Python,关于正则表达式相对来说还是比较难的,主要是细节比较多。而Python本人还没有研究过,有机会尝试一下,如果您还有什么好的方法欢迎笔者联系,相互学习与讨论。
我们基本上可以按照上面的思路去实现,只需要做少部分的修改,这里大致说一下
- 1:准备阶段根据你需要的数据会有不同的html产生
- 2:产生不同的html之后你html内部的结构就会做响应的变化,这个时候你就要去把java那段核心代码搞懂来就没问题了,最重要的还是这里。
- 3:根据对应的NSArray数据写入到plist文件中,这里是iOS开发中常用的技术我就不多说。