之前写过一篇关于可视化爬虫spiderflow的文章,介绍了基本语法并实战了某校园新闻数据的爬取。
还有一篇文章介绍了基于docker-compose快速部署spiderflow的过程,需要部署的话可参考该文章。
文章链接如下:
本文继续记录一下天气数据爬取的过程,供实现参考。
近期接到运营中心一个业务需求,希望能获取到指定区域的天气数据,用于大屏展示,需要的参数包含:
分析原始需求可分为三部分数据:
具体说明如下:
1、关于天气数据的获取我们取中央气象台的数据,网址为: 西安-天气预报 (nmc.cn)
上面网址是在页面上搜索框输入了西安后查询的数据页面,页面展示内容如下:
可以看到官方这个页面上包含了我们需求提到的天气相关的所有数据。
2、预警数据我们使用的网页为: 中央气象台官方网站-预警信号 (nmc.cn)
列表里可以选择省份以获取指定省份的预警数据,这里我们以陕西省为例,页面展示如下:
详情页我们需要获取到预警内容用于展示。
部署过程可参考【工作记录】基于docker-compose快速部署springboot应用的实践
准备一个数据库用于存放对应数据
要求能通过spiderflow服务器访问到该数据库即可
通过spiderflow的页面,添加上面准备好的数据源,用于后续爬虫中的数据保存
进入西安天气预报页面,网址为西安-天气预报 (nmc.cn)
打开开发者工具,找到网络-Fetch/XHR,可以看到如下界面:
可以看到区域数据是通过接口请求到的,在标头和负载可以看到具体的请求地址可参数。
在区域数据下面还有另外一个接口数据,如下:
具体结构如下:
至此天气相关数据就基本涵盖全了,只需要获取到相关数据并保存入库即可。
继续打开预警列表页面,选择陕西省,打开开发者工具,找到网络-Fetch/XHR
这样就找到了预警列表和预警内容的数据,同样需要获取到然后入库保存即可。
打开爬虫web界面,进入爬虫列表,点击添加爬虫,命名为天气区域数据获取
拖入需要的组件并连接起来,分别是爬虫组件、循环组件和SQL组件,配置如下:
说明如下:
配置的地址即上面提到的获取区域数据的地址,爬虫完成后会得到一个resp
的变量,也就是返回的json数据,我们可以通过${resp.json}
获取到变量的数据。
循环组件配置循环或集合参数为${rs.json}
, 添加循环后可以得到item和index两个变量分别对应循环中的每一项和循环中的索引。
执行SQL组件需要配置链接的数据源及需要执行的SQL脚本,脚本中可使用流程中的变量,这里我们用到的就是item
执行SQL组件配置如下图:
说明如下:
脚本很简单跟正常的sql差不多,只不过里面的变量是通过#${XXx}#
来写的。
这里示例的是mysql数据库,其他数据库如有必要根据语法做相应修改即可。
表结构也比较简单,就截图中的字段加上一个ID自增主键和create_time创建时间,建表语句就不在这里贴了。
至此区域数据爬取并保存完成。
前面我们提到区域表中存在一个字段enabled,如果为1的话我们才爬取它的数据,所以在爬虫中应该是这样一个流程:
具体配置过程如下:
说明如下:
1. 第一个执行SQL组件是为了筛选出所有enabled为1的区域数据,配置的sql也很简单,
select * from `mapdesign`.weather_zone where enabled = 1;
执行完成后会得到一个rs的变量,可以通过rs.json
将数据转换成json结构方便后续使用, 通过${rs.json}
来取值。
2. 循环的集合配置的就是上面sql的结果: ${rs.json}
循环流程后会得到item和index两个流程变量,分别对应每一条数据和集合中的索引。
3. 爬虫组件配置如下:
主要配置的就是个URL,可以根据页面上的接口地址看出拼接规律,item.code就是区域数据中的code值。
爬虫完成后会得到一个resp
的变量, 可以通过resp.json
转换成json结构,通过${resp.json}
来取值使用。
4. 定义变量
为方便sql中变量的使用,我们可以使用定义变量组件提前定义好一些变量及其取值规则。
具体配置如下:
结合上面分析的天气数据的数据结构,相对来说比较好理解,不做赘述。
5. 执行SQL
前面已经定义好了变量,sql中便可以通过#${变量名}#
来使用了。
脚本配置如下:
insert into mapdesign.weather_data(`date`, city_code, `real`, `predict`, `last`, update_time, publish_time)
values(date(now()), #${item.code}#, #${real}#, #${predict}#, #${last}#, now(), #${pt}#)
on duplicate key update `real`=#${real}#, `predict`=#${predict}#, `last`=#${last}#, update_time=now(), publish_time=#${pt}#
weather_data表设计比较简单,所有数据都是以json结构存储的,除脚本中涉及到的字段外还有个ID自增主键。
这里的数据保存设计就比较随意了,各位可以根据自己的喜好自行设计保存即可。
完成后点击工具栏的保存按钮,然后可以点击保存按钮右侧的侧三角来运行,观察数据库数据即可。
正常情况不保错的话就可以正常入库了。
结果数据如下:
至此天气数据的获取与保存就完成了。
预警数据涉及到列表数据和详情数据的获取,需要两个爬虫和一个循环,设计如下流程:
说明如下:
定义变量
在预警列表页面随便点击一个预警进入详情,可以看到详情页面的地址拼接方式为 "http://www.nmc.cn/publish/alarm/"+ ${item.id}.html
, 这里定义的变量就是为了取到所有的列表数据json
变量名为datalist
, 变量值为${resp.json.jsonpath("data").jsonpath("page").get("list")}
循环
循环组件不过多解释,循环的即可就是上面定义好的datalist
, 即${datalist}
爬虫
这个爬虫就是为了获取详情页面数据的,url配置为: http://www.nmc.cn/publish/alarm/${item.id}.html
需要注意的是这里获取到的是一个html页面,我们需要通过路径匹配来取到页面中我们需要的数据。
定义变量
这里主要是为了取到详情页面中的预警内容数据。
配置变量名为alarmContent
,变量值为${resp.html.selector("#alarmtext>p").text()}
。
这个表达式的含义就是说取html中的id为alarmtext下面的p标签的文本内容
执行SQL
除了alarmContent之外其余的数据都可以通过列表取到,如id, publish_time, title, icon
等,在sql中使用#${item.xxx}#
即可取到。
最终配置的sql脚本如下:
insert into `mapdesign`.alarm_data(alarm_id, title, icon, url, publish_time, update_time, alarm_content)
values(#${item.alertid}#, #${item.title}#, #${item.pic}#, #${item.url}#, #${item.issuetime}#, now(), #${alarmContent}#)
on duplicate key update title = #${item.title}#, alarm_content=#${alarmContent}#
库名、表名、字段名及语法均可根据实际情况进行修改。
设计完成后保存运行,没有报错的话数据就可以正常入库了。
最终获取到的预警数据如下:
至此预警数据获取与保存就完成了。
本文记录了从分析到实践到测试完成天气数据爬取的过程,记录的比较细致。
作为一种实现思路,希望能对大家完成相关业务有所帮助。
对以上内容有任何疑问或者建议欢迎留言评论,看到后会及时回复~~~
创作不易,欢迎一键三连~~~