作为一个初步学习用FME获取网络数据的新手,丁香园的疫情统计数据算是非常简单的了,非常适合于入门学习。
为什么说简单呢,访问丁香园的网址:https://3g.dxy.cn/newh5/view/pneumonia?scene=2&clicktime=1579584868&enterid=1579584868&from=timeline&isappinstalled=0
查看源代码,我们可以发现,所有我们需要的数据全都存放在一个ID名为"getAreaStat"的script标签中,只要获取到这个标签,解析出JSON数据,就可以了。
一、请求页面,获取疫情JSON数据
数据获取流程如下:
首先用HTTPCaller获取源代码,在Request URL位置输入网址:
设置目标属性的字符编码为:UTF-8。
利用HTMLExtractor转换器拾取ID名为getAreaStat的标签:
二、数据格式修整:
这个时候,获取的数据还不是最终的JSON数据,它是一个:“try { window.getAreaStat = [……]}catch(e){}”的代码。
我们甚至不需要清楚这串代码是用来做什么的,可以粗暴地将看作是一串“try { window.getAreaStat =”字符串,加一系列存储疫情数据的JSON数组,后面加“}catch(e){} ”字符串。
通过StringReplacer和AttributeKeeper,对数据格式进行处理,剔除不必要的字符串,最终获得一个存储JSON数据的数组。
三、解析JSON:
第一层JSON:
在对这个JSON数据列表进行解析的时候我犯了难,因为这是一个以全国省份划分的列表数据嵌套了各省JSON数据,每个省的JSON里再嵌套各市的JSON的数据格式。
想要解析这个数据格式就比较麻烦了,最终我选择用JSONFragmenter转换器,粗暴地将第一层JSON全部解析出来最终再AttributeManager的相邻元素属性给各省份的数据“TYPE”属性动态赋值,然后根据各省份的TYPE属性分组合并的方法处理第一层JSON数据。
具体操作如下:
JSONFragmenter转换器JSON Query设置为json[*],运行转换器。
结果如下:
可以看到,这样解析出来后,大约每9条数据,才是一个完整的包含各省确诊人数、死亡人数、治愈人数、可疑人数还有每个城市详细数据的JSON数据,但它的各项数据是动态的,并不是每个省份的格式都一样(如香港、澳门、*)。并不能单纯的认为每9条数据可以合并为一个完整数据。
就比如一开始我做这个模版的时候,当时这段源代码里还没有locationId这个属性,如果上面的方法,丁香园上的数据每一次小改动。都得重新修改一次模版。那这就太蠢了。
这个时候,相邻数据属性方法就派上了用场,先用AttributeCreator创建一个type属性,设置默认属性为0。再用AttributeManager,启动相邻要素属性,设置默认type属性与上一个要素相同,每当json_index属性为provinceName时,则type加1。
(相邻要素属性详细用法请参照往期博客:https://blog.csdn.net/fmechina/article/details/91854162)
具体参数设置如下:
查看运行结果,可以发现每个省都给赋值了不同的type属性,下一步则可以用ListBuilder根据type属性分组,将每个省的数据整合到一起。
用ListBuilder根据type属性分组,将每个省的数据整合到一起后,每一条数据都是一个包含了属性和值的数组,如何将这个属性暴露出来,又是一个问题。
最终我用的是PythonCaller转换器,将属性与值合并,具体代码如下:
再用AttributeExposer将我们需要的属性暴露出来,最终结果如下:
第二层JSON:
这个时候,只有最后一层JSON需要处理,相对来说,就简单了很多。用JSONFlattene转换器设置参数如下:
最终再处理一下属性,将英文属性名称改为中文,大功告成。
用FME获取丁香园疫情数据整体流程其实比较简单的,关键一点是获取到JSON数据之后怎么去解析它。当然,身为一个giser,获取数据不是最重要的,最重要的是如何去分析数据,用获取到的疫情数据去做更有意义的事情。