网络爬虫-使用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核心代码:

 1   try {
2
3       //文件路径
4
5         String path = " /Users/icocos/Desktop/iCocos.html";
6
7
8
9         //加载网页
10
11         Document doc = Jsoup.parse(new File(path), "UTF-8");
12
13
14
15         //解析网页
16
17         Elements lis = doc.select("li");
18
19
20
21         //遍历数组
22
23         for(int i = 0; i < eles.size(); i++) {
24
25         //根据i获取对应的元素
26
27         Element li = lis.get(i);
28
29
30
31         //取图片
32
33         Element img = li.select("img").get(0);
34
35         // System.out.println(img.attr("src"));
36
37
38
39         //获取图片名
40
41         String imgName = img.attr("src");
42
43
44
45         Element p = li.select("p").get(0);
46
47         String personName = p.text();
48
49
50
51         //打印数据
52
53         System.out.println(imgName + "," + personName);
54
55
56
57       }
58
59      } catch {
60
61     //错误(异常)处理
62
63     e.printStackTrace();
64
65 }

此时点击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数据如下;

 1 public class iCocos {
2
3 public static void main (String[] args) {
4
5     try {
6
7       //文件路径
8
9       String path = " /Users/icocos/Desktop/iCocos.html";
10
11       //加载网页
12       Document doc = Jsoup.parse(new File(path), "UTF-8");
13
14       //解析网页
15       Elements lis = doc.select("li");
16
17       System.out.println("NSArray *apps = @[");
18
19
20       //遍历数组
21
22       for(int i = 0; i < eles.size(); i++) {
23
24       //根据i获取对应的元素
25
26       Element li = lis.get(i);
27
28
29       //取图片
30
31       Element img = li.select("img").get(0);
32
33       // System.out.println(img.attr("src"));
34
35       //获取图片名
36
37       String imgName = img.attr("src");
38
39       Element p = li.select("p").get(0);
40
41       String personName = p.text();
42
43       //打印数据
44       // System.out.println(imgName + "," + personName);
45
46       System.out.println("@{@\"name\":@\"" + personName + "\", @\"icon\":@\""+ imgName + "\"},");
47       }
48       System.out.println("]");
49
50     } catch {
51
52       //错误(异常)处理
53       e.printStackTrace();
54
55     }
56
57   }
58
59 }

这个时候回打印输出下面的代码,

下面我们就需要在xcode中做事情了,做什么事呢,就是将输出的以NSArray开头的所有数据在Xcode中转换为plist的数据,当然你也可以不转换,做少部分的修改之后直接使用JSON解析技术去解析,但是那样不是最好的办法。

在Xcode中新建一个项目工程,在ViewDidLoad中粘贴拷贝过来的代码,这个时候是不是看起来非常熟悉,对了,她就是我吗开发中常用到的数组数据。

下面我就使用循环遍历去讲NSArray数组数据写到plist文件中。

 1 - (void)viewDidLoad
2
3 {
4
5 [super viewDidLoad];
6
7
8
9 NSArray *apps = @[
10
11 @{@"name":@"敌法师", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/dfss.jpg"},
12
13 @{@"name":@"火枪", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/arjj.jpg"},
14
15 @{@"name":@"德鲁伊", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/dlyy.jpg"},
16
17 @{@"name":@"月骑", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yzqs.jpg"},
18
19 @{@"name":@"变体精灵", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/btjl.jpg"},
20
21 @{@"name":@"娜迦海妖", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/njhy.gif"},
22
23 @{@"name":@"猴子", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/hycm.jpg"},
24
25 @{@"name":@"白虎", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yzjs.jpg"},
26
27 @{@"name":@"隐形刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yxck.jpg"},
28
29 @{@"name":@"巨魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/jmzj.jpg"},
30
31 @{@"name":@"直升机", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/arzs.jpg"},
32
33 @{@"name":@"赏金猎人", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Naka.gif"},
34
35 @{@"name":@"骷髅射手", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/KLSS.gif"},
36
37 @{@"name":@"育母蜘蛛", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YMZZ.gif"},
38
39 @{@"name":@"血魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/XM.gif"},
40
41 @{@"name":@"黑暗游侠", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Nbrn.gif"},
42
43 @{@"name":@"虚空假面", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/EC45.gif"},
44
45 @{@"name":@"蛇发女妖", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/H00V.gif"},
46
47 @{@"name":@"地卜师", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/H00I.gif"},
48
49 @{@"name":@"地穴刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/DXCK.gif"},
50
51 @{@"name":@"蚂蚁", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/DXBZ.gif"},
52
53 @{@"name":@"幻影刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/HYCK.gif"},
54
55 @{@"name":@"闪电幽魂", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/E002.gif"},
56
57 @{@"name":@"影魔", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YM01.gif"},
58
59 @{@"name":@"小鱼人", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/yryx.gif"},
60
61 @{@"name":@"幽鬼", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/YG1.gif"},
62
63 @{@"name":@"圣堂刺客", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/E01Y.gif"},
64
65 @{@"name":@"灵魂守卫", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/LHSW.gif"},
66
67 @{@"name":@"熊战士", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Huth.gif"},
68
69 @{@"name":@"剧毒术士", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/JDSS.gif"},
70
71 @{@"name":@"冥界亚龙", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/MJYL.gif"},
72
73 @{@"name":@"复仇之魂", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/Hvwd.jpg"},
74
75 @{@"name":@"剑圣", @"icon":@"http://dotadb.uuu9.com/UploadFiles/Dota/Hero/jsjs.jpg"}
76
77 ];
78
79
80
81 [newApps writeToFile:@"/Users/icocos/Desktop/apps.plist" atomically:YES];

这个时候我吗的左面就有了这个plist文件,打开之后你会看到

最后的步骤就是图片的下载,

//简单写入

 1 //    for (NSDictionary *dict in apps) {
2
3 // NSString *icon = dict[@"icon"];
4
5 //
6
7 // // 新建网络图片的URL路径
8
9 // NSURL *url = [NSURL URLWithString:icon];
10
11 //
12
13 // // 下载图片的二进制数据
14
15 // NSData *data = [NSData dataWithContentsOfURL:url];
16
17 //
18
19 // // 截取文件名
20
21 // NSString *filename = [icon lastPathComponent];
22
23 //
24
25 // // 文件路径
26
27 // NSString *iconPath = [NSString stringWithFormat:@"/Users/icocos/Desktop/Icons/%@", filename];
28
29 //
30
31 // [data writeToFile:iconPath atomically:YES];
32
33 // }

//由于plist中图片名使用的都是对应链接的最后一个名字,所以我们不能使用上面的方法,还需要做一些处理,才能真正使用

 1     NSMutableArray *newApps = [NSMutableArray array];
2
3 for (NSDictionary *dict in apps) {
4
5 NSMutableDictionary *newDict = [NSMutableDictionary dictionary];
6
7 newDict[@"name"] = dict[@"name"];
8
9 newDict[@"icon"] = [dict[@"icon"] lastPathComponent];
10
11 [newApps addObject:newDict];
12
13 }
14
15
16
17 [newApps writeToFile:@"/Users/icocos/Desktop/apps.plist" atomically:YES];
18
19
20
21 }

图片下载完成之后你会回看到对应的文件夹中快速的出现了好多的图片

此时我们就得到了一份和网页想相对应比较完整的plist数据,后面我们要做的就是将我们的plist数据显示到界面,后面我就不介绍了,详细请看:plist文件读取

最后总结一下,如果以后遇到了关于需要抓取网络数据实现网络爬虫的功能的时候,我们基本上想到的第一种方法就是使用java语言,当然公司一般不会有这样的要求,公司一般都是使用自己服务器的api来实现,特殊情况除外。

当然你也可以使用正则表达式或者Python,关于正则表达式相对来说还是比较难的,主要是细节比较多。而Python本人还没有研究过,有机会尝试一下,如果您还有什么好的方法欢迎笔者联系,相互学习与讨论。

我们基本上可以按照上面的思路去实现,只需要做少部分的修改,这里大致说一下

  • 1:准备阶段根据你需要的数据会有不同的html产生
  • 2:产生不同的html之后你html内部的结构就会做响应的变化,这个时候你就要去把java那段核心代码搞懂来就没问题了,最重要的还是这里。
  • 3:根据对应的NSArray数据写入到plist文件中,这里是iOS开发中常用的技术我就不多说。

iOS—网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据的更多相关文章

  1. iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据

    网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...

  2. iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据

    网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...

  3. iOS开发——网络使用技术OC篇&网络爬虫-使用正则表达式抓取网络数据

    网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...

  4. 【python网络编程】新浪爬虫:关键词搜索爬取微博数据

    上学期参加了一个大数据比赛,需要抓取大量数据,于是我从新浪微博下手,本来准备使用新浪的API的,无奈新浪并没有开放关键字搜索的API,所以只能用爬虫来获取了.幸运的是,新浪提供了一个高级搜索功能,为我 ...

  5. 网络爬虫-使用Python抓取网页数据

    搬自大神boyXiong的干货! 闲来无事,看看了Python,发现这东西挺爽的,废话少说,就是干 准备搭建环境 因为是MAC电脑,所以自动安装了Python 2.7的版本 添加一个 库 Beauti ...

  6. iOS开发——实用技术OC篇&单例模式的实实现(ACR&MRC)

    单例模式的实实现(ACR&MRC) 在iOS开发中单例模式是一种非常常见的模式,虽然我们自己实现的比较少,但是,系统却提供了不少的到来模式给我们用,比如最常见的UIApplication,No ...

  7. iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果

    8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...

  8. iOS开发——实用技术OC篇&简单抽屉效果的实现

    简单抽屉效果的实现 就目前大部分App来说基本上都有关于抽屉效果的实现,比如QQ/微信等.所以,今天我们就来简单的实现一下.当然如果你想你的效果更好或者是封装成一个到哪里都能用的工具类,那就还需要下一 ...

  9. iOS开发——实用技术OC篇&事件处理详解

    事件处理详解 一:事件处理 事件处理常见属性: 事件类型 @property(nonatomic,readonly) UIEventType     type; @property(nonatomic ...

随机推荐

  1. 谈FME批量自动化数据转换方法

    FME作为转换神器,支持几百种格式的互转,实现互操作化.从fme.exe执行方式入手,讨论Command命令式执行模板(.fmw/.fmwt)和脚本(.tcl/.py)实现自动化批量转换. 1.fme ...

  2. 【Thinking in Java】Java Callable的使用

    Callable<>和Runable类似,都是用于Java的并发执行. 唯一的区别是,Runable的run方法的返回是void,而Callable的call方法是有返回值的. call方 ...

  3. winRT Com组件开发流程总结

    winRT Com组件开发: 1.编辑idl文件,winRT COM的idl文件与win32的idl文件有差异,如下: interface ItestWinRTClass; runtimeclass ...

  4. Linux内核分析之扒开系统调用的三层皮(下)

    一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ...

  5. (01背包变形) Cow Exhibition (poj 2184)

    http://poj.org/problem?id=2184   Description "Fat and docile, big and dumb, they look so stupid ...

  6. ASP.NET 导出gridview中的数据到Excel表中,并对指定单元格换行操作

    1. 使用NPOI读取及生成excel表. (1)导出Click事件: 获取DataTable; 给文件加文件名: string xlsxName = "xxx_" + DateT ...

  7. CocoaPods的版本升级

    我们在项目开发过程中为了更好的管理项目中引用的一些第三方的开源代码,我们在项目开发中都会使用CocoaPods,在项目中不使用Cocoapods可以绕过这篇帖子,但是Cocopods升级比较快,但是怎 ...

  8. String、String.valueOf、toString 它们三者的区别总结

    今天在使用这个的时候发现,他们三者好像在某些场所都是可以用的,但是不免会让人想到那既然它们三者这么的相似,那么总有些什么区别吧.我也在网上找了一些资料看.自己也看了API文档,就将他们三的区别总结一下 ...

  9. idlcpp 功能改进

    最近没有续写 idlcpp 的教程, 因为忙着对它进行大幅度的修改. 一开始本是计划用idlcpp对付新写的代码,让这些新写的代码能够很容易提供给脚本使用.后来又希望能将大量现存的代码移植过来,毕竟有 ...

  10. 【转】各种语言中的urlencode方法

    URLENCODE和URLDECODE是比较常用的URL参数转换方法,为以后使用方便,自己归类一下.   原文地址:http://blog.sina.com.cn/s/blog_3f195d25010 ...