MENU

【代码札记】使用Java批量获取日本和色的数据

June 20, 2018 • Read: 287 • 瞎折腾

前些日子闲来无事,花费了两天时间写了一个能够获取日本和色数据的程序。这里将记录在开发过程中遇到的心得和小记。

项目地址: Github

简述

这个项目起始于我看到了一个网站:NipponColors。这个网站用Js展示了大约250种日本和色的RGB数据和CMYK数据,然而hp祖传的72%NTSC色域屏幕势必是没法欣赏全部了。但是我这个人就有一点,我喜欢收集数据,而且一定要全。因此我有额外查了几个网站,发现和色似乎不只250种,有些网站说有400多种。于是我选取了3个网站: NipponColorsIroCoreColorDic。后者分别和色的百科和词典。

爬取数据

关于程序本身,我试用了Java,并且一开始只是觉得是个小项目,对于网络处理这里并没有大动干戈地使用Apache软件基金会的HttpClient,而是直接面向复制粘贴编程,从网上找了一个脍炙人口的HttpRequest类来处理Post和Get请求。效果还是挺好的,极少数情况下会有连接超时。

对于不同的网站我分别使用了三段代码进行抓取,但是本身流程是大体相同的:抓取网页数据->提取包含信息的部分->将这部分分割成数组->循环处理。

NipponColors

NipponColors应当是三个网站中最简单的一个。通过Chrome查看网页源代码只抓取到了网站对于颜色的编号以及颜色的名称和罗马音。通过对Css文件的查看也没有发现有RGB或CMYK的数据,因此使用Chrome查看网络活动情况,由此发现每次查询颜色时,通过Post方法请求后台的一个php文件即可得到对应颜色的序号、CMYK和RGB。因此在最初的程序设计上获取到一个完整的颜色信息需要两个步骤:

首先提取主页的颜色列表,通过一系列暴力分离得到颜色的名称和对应的罗马音。将这些颜色数据储存在一个ArrayList种。
其次使用for循环迭代ArrayList,取每一个颜色数据的罗马音封装成post请求向网站获得具体的序号、CMYK和RGB数据。
最后使用json的格式储存到文件中。这一步是程序大体框架完成时才想到的。

为了方面处理数据,我遵循面向对象编程的原则,建立了一个Color类,其中有index、CMYK、RGB、Name、Roma等字段用以储存信息。

ColorDic

这个是我第二个实现的网站。这个网站比较好的地方在于它将颜色的名称和假名还有RGB都放在了一起,然而最初我并没有点击细看,以为这网站只提供RGB数据而没有CMYK,因此一开始并没有获得CMYK数据。

获取的流程也和上面一样,只不过使用的符号不同。我至今每太弄明白正则表达式,因此连续使用了多个split进行文本分割。具体代码可以看Github,在ColorGetter这个类中。

IroCore

这个是我实现的第三个网站。和上面一样,唯独不同之处在于每个颜色的RGB和CMYK数据都要点开,通过爬去首页只能获得名称和罗马音。而且这个网站首页的表格不是很严谨,需要在程序中判断一下分割出来的每一条数据是否是有效的(代码中在循环数组开头的if判断)。因此流程和NipponColors一样,先获取总共的列表,再详细的填充数据,然而这个地方和我想象的不太一样。

对于颜色的详细页面,我原本以为就是固定的url+罗马音,然而有时会遇到程序报404,我发现了如下几种情况:

1.特殊字符:ō,例如赤香色获取到的罗马音是Akakō-iro,然而实际上映射到url中的却是akako-iro
2.名称变化:这个是遇到的最多的,其中一种情况是名称变化,例如勝色,其罗马音是Katsu-iro,但是url中是kachiiro。

这些变化对于讲日语的人来说很好处理,可是程序则不然。因此我在Color类中新增加了url变量用以储存在主页面中获取到的对应颜色的url,在填充数据的时候直接访问这个就行了。

colorDic的细化

上面说的,开始我只获取到了ColorDic的RGB字段,CMYK完全没有注意到。拜IroCore所赐,现在的程序已经能够很容易的迁移出获取CMYK的代码了。因此进一步完善程序之后这样一个大体框架就做好了。

优化

然而目前问题有两个:一个是程序单线程运作,完成的获取一次需要大约半个小时(根据网速),并且每次调试都很费时间。因此我有两点优化:使用多线程和Json储存数据。

多线程

为了避免多线程带来的安全问题,我将三个网站分成三个线程,每个网站独立获取、三个网站同时获取数据,这样子就能够迅速很多,也避免了同步锁带来的一系列问题。

在多线程上,我在主线程调用上述三个线程的join函数来等待三个线程执行完毕在进行后续操作。

Json

这里我试用了Google的gson 2.8.5,我一直觉得gson最好用了,你给它一个实体他就能根据类的定义输出Json,反过来通过json生成实体也是一样的方便。因此通过代码的选择可以一次获取之后储存成json文件,然后后续根据实际用途可以输出(我覆盖的Color类的toString方法使之在print时更加适合人类阅读)浏览或者生成Markdown表格和SVG文件。

结果

如下是今天下午运行时得到的结果,由于文章长度有限,Markdown表格不在此展示,请移步Github。至于颜色预览方面,目前是通过Java绘制不同颜色的矩形来实现。先让Java输出SVG代码,再利用工具将SVG代码转换为方便浏览的png图片。图片可用于浏览,表格方便复制出数据。

图片:ClickHere!


全文完。


知识共享许可协议
【代码札记】使用Java批量获取日本和色的数据天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://www.skyblond.info/about.html 处获得。

Archives QR Code Tip
QR Code for this page
Tipping QR Code
0:00