📃目录跳转

📚简介:

       这一篇文章的定义已经不是教程篇了,教你如何通过自己的需求来完成功能,有的时候我们会遇到处理一些事情时,我们自己没办法解决,但是可以通过第三方服务解决时一般通过以下方式解决。

通常有3种情况:

  1. 购买第三方的服务,或者入驻开发者。
  2. 自己通过分析第三方服务商接口拿到自己想要的信息
  3. 我们分析不了,大概率只要钱给够,第三方都会提供对应的服务。

💨需求:

    我这里就以之前文章,通过公众号定时推送天气信息给好友为例,其中通过好友设置不同城市,获取不同天气这个案例中,随着日期的改变,天气的情况也会跟着改变,那么就需要通过接口查询天气情况等

完成方式有2个或者更多,我这里就说我了解的几个方案,

  1. 通过入驻开发者获取秘钥信息,调用平台接口获取到值也是比较完善的并且是json格式返回后续不需要过度处理,但是人家为什么给你免费用呀,要不就是有调用的次数或者是超过以后要收费。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java

  1. 自己通过分析第三方接口,拿到自己想要的信息。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_02

🎉自己分析接口:

    对于我来说,写文章我既没有挣到钱,也没有靠软件卖钱,纯纯的技术分享,让小白也可以完成公众号推送天气,并且作为开发者来说,不应该出现玩一玩学习下还要花钱才能完成,我相信还是有很多学生读者朋友们,那么更应该不花钱并且挑战下自己。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_03

    自己分享下获取​​中国天气网​​的数据,既然他要展示那么肯定会请求后端接口,获取城市信息,就算返回的不是json数据我们也可以想办法解析出自己需要的数据。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_json_04


     分析接口数据,最好是可以想到网站会在那个页面展示最全的数据信息,这样我们获取到的数据就越多。

点击页面天气信息

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_json_05

     点击进入可以看到,天气的实时温度,湿度,风速,空气质量等信息,其实后台返回的接口数据不止这些,还有挺多的数据没有被展示出来

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_数据_06

💭分析请求接口:

      在浏览器中按​​F12​​​,或者右键选择​​检查​​​会跳出控制台,我们选择网络哪项,我这个是中文的如果你们是英文那应该是​​Network​

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_07

然后分析请求的信息,可以排除​​png,jpeg​​类型请求,因为这个类型是图片。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_json_08


然后查看请求文件的响应内容,然后查看响应的数据是不是存在有用的

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_json_09

我什么要叫你们看响应内容是有原因的,有些接口返回的数据在预览里面会出现乱码

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_10


所以你们可以先看预览如果乱码那么就在看响应里的数据。

🌤️分析出当天天气接口:

我是一个一个请求响应看过去,看到了这个文件有我想要的数据

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_11

请求地址:http://d1.weather.com.cn/dingzhi/101230101.html

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_12

响应数据内容

var cityDZ101230101 ={
"weatherinfo": {
"city": "101230101",
"cityname": "福州",
"fctime": "202209061100",
"temp": "34℃",
"tempn": "25℃",
"weather": "多云",
"weathercode": "d1",
"weathercoden": "n1",
"wd": "东风转东北风",
"ws": "<3级"
}
}
var alarmDZ101230101 ={"w":[]}

我把内容排版优化下是不是可以看出,我们需要的关键信息,​​有城市,最高温度,最低温度,天气类型,风速等信息​​。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_13


从图中可以看出前面那个接口获取的是当天的天气,并​​没有包含实况的天气信息​​,就是左侧展示的数据,那么我们接着查找接口信息。

☁️分析出实况天气接口:

接着往下面找,可以看到预览里面的数据对应这实况数据。那么该接口就是实况天气接口

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_14

请求地址:
​​​ http://d1.weather.com.cn/sk_2d/101230101.html​

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_15

响应数据内容

var dataSK={
"nameen": "fuzhou",
"cityname": "福州",
"city": "101230101",
"temp": "27",
"tempf": "80",
"WD": "微风",
"wde": "NWW",
"WS": "2级",
"wse": "10km\/h",
"SD": "63%",
"sd": "63%",
"qy": "1003",
"njd": "24km",
"time": "17:35",
"rain": "0",
"rain24h": "0",
"aqi": "50",
"aqi_pm25": "50",
"weather": "多云",
"weathere": "Cloudy",
"weathercode": "d01",
"limitnumber": "",
"date": "09月06日(星期二)"
}

我把内容排版优化下是不是可以看出,​​实况温度,时间,湿度,风速,以及pm2.5的信息​​。


🧐思考问题(关键):

        但是你会发现一个问题他们的请求路径当然是不一样的,我想说的是当天天气请求地址,我没办法通过固定请求返回其他城市的天气,并且没有办法传递城市参数,仔细看接口你会发现这2个接口除了前面路径不一样后面一样都是 ​​101230101.html​​​,但是我当时不知道这个​​101230101​​含义是什么,但是可以联想到这个肯定与我查询福州天气有关系。

​当天天气​​请求地址:http://d1.weather.com.cn/dingzhi/101230101.html

​实况天气​​​请求地址:
​​​ http://d1.weather.com.cn/sk_2d/101230101.html​

不知道你们也没有注意到查询的接口中有个​​city.js​​的请求

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_16

查看预览信息,我们可以看到好多城市的信息,并且其中有个​​AREAID​​参数,表示城市所在地的标识,并且这个格式和上面的还挺像

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_17


于是我就去响应里面搜索了下福州的​​101230101​​标识

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_18


发现存在参数中,所以要想知道我要查询那个城市的提取就必须从该接口中找到​​AREAID​​的编号。

​城市AREAID​​​请求地址:
​​​ https://j.i8tq.com/weather2020/search/city.js​

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_19


        但是这个格式是后端特意以这样格式返回前端使用,对于我们来说我们只有把返回的数据按照最下单位获取出来如:

{
"北京": {
"北京": {
"北京": {
"AREAID": "101010100",
"NAMECN": "北京"
},
"海淀": {
"AREAID": "101010200",
"NAMECN": "海淀"
},
"朝阳": {
"AREAID": "101010300",
"NAMECN": "朝阳"
},
"顺义": {
"AREAID": "101010400",
"NAMECN": "顺义"
}
}
}
}

这个是省略了一些北京各地点的天气情况,他们都是有层级关系的我们只有获取到最里面那层结构使用

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_20


你们会怎么把该数据提取出来呢?评论区走一波,看看也没有更好的方法。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_21

我分析了下,该接口的数据他是有层级格式的,按照​​省>市>区​​展示

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_22

那既然是三层结构,那我是不是可以提供循环遍历三层,在把​​最后一层​​​数据​​保存​​​在一个​​Map集合​​中。


🔭验证猜想:

      假设我这已经把城市数据提取到一个Map中,接着我们要查询北京天气,在通过城市名称从Map中获取出对应的​​AREAID​​值

写代码前,先验证下我们的猜想是否正确。

使用请求工具拼接路径查看请求结果,工具可以是​​ApiPost,PostMan​​等工具:

获取实时天气:(北京)

"北京": {
"AREAID": "101010100",
"NAMECN": "北京"
}

可以看出返回了北京的天气,为了验证我们打开天气网查看北京今天天气。

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_数据_23

响应数据:

var dataSK={
"nameen": "beijing",
"cityname": "北京",
"city": "101010100",
"temp": "28",
"tempf": "82",
"WD": "微风",
"wde": "NWW",
"WS": "2级",
"wse": "6km\/h",
"SD": "25%",
"sd": "25%",
"qy": "1014",
"njd": "30km",
"time": "10:30",
"rain": "0",
"rain24h": "0",
"aqi": "27",
"aqi_pm25": "27",
"weather": "多云",
"weathere": "Cloudy",
"weathercode": "d01",
"limitnumber": "4和9",
"date": "09月07日(星期三)"
}

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_24


可以看出是一一对应上的,那么另外一个接口我就不测试了。

注意:请求头一定要添加

​Referer:http://www.weather.com.cn/​​这个的作用就是为了防盗链和防止恶意请求

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_java_25

🎃代码编写:

      编写的案例,使用的是SpringBoot脚手架创建Spring项目。可以查看往期内容的SpringBoot项目创建跳转

配置下application.yml

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_数据_26


创建一个​​WeatherService​​ 类

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_json_27

pom.xml引入坐标

<!--hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.1</version>
</dependency>

🗺️城市AREAID获取:

我们先把城市的js数据解析出来
​​​城市AREAID​​请求地址:

https://j.i8tq.com/weather2020/search/city.js

代码:

public static JSONObject getCity(){
String cityjs="https://j.i8tq.com/weather2020/search/city.js";
//发送请求获取数据
String cityStr = HttpUtil.createGet(cityjs).header("Referer", "http://www.weather.com.cn/").execute().body();
//需要解析数据
String cityJson = cityStr.replace("var city_data =", "");
//创建集合存储数据
//使用 NAMECN:AREAID
Map<String, Long> map = new HashMap<>();
JSONObject entries = JSONUtil.parseObj(cityJson);
Set<String> keys = entries.keySet();
for (String key : keys) {
System.out.println("第一层 省" + key);
Set<String> citys = entries.getJSONObject(key).keySet();
for (String city : citys) {
System.out.println("--第二层 城市" + city);
Set<String> areas = entries.getJSONObject(key).getJSONObject(city).keySet();
for (String area : areas) {
System.out.println("---第三层 区:" + area);
JSONObject jsonObject = entries.getJSONObject(key).getJSONObject(city).getJSONObject(area);
System.out.println(jsonObject.toString());
map.put(jsonObject.getStr("NAMECN"), jsonObject.getLong("AREAID"));
}
}
}
//把map数据转换成json
String jsonStr = JSONUtil.toJsonStr(map);
System.out.println(jsonStr);
return JSONUtil.parseObj(map);
}

运行结果如下:

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_28


可以看出解析出来的数据就是以​​NAMECN:AREAID​​格式

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_html_29

🎢城市实况天气获取:

​实况天气​​请求地址:

http://d1.weather.com.cn/sk_2d/传入城市的AREAID.html

代码:

public static void main(String[]) {
//getCity();
JSONObject realWeather = getRealWeather("南平");
System.out.println(realWeather.getStr("cityname")
+" 天气:"+ realWeather.getStr("weather")
+" 温度:"+ realWeather.getStr("temp")
+" 湿度:"+ realWeather.getStr("sd")
+" Pm2.5:"+realWeather.getStr("aqi_pm25")
);
}
/**
* 获取实时城市天气
* @param city
* @return
*/
public static JSONObject getRealWeather(String city){
//获取出所有城市的AreaId
JSONObject cityAreaId = getCity();
//取出对应城市的areaid
String areaId = cityAreaId.getStr(city);
//实时天气的地址
String REALWEATHER_URL="http://d1.weather.com.cn/sk_2d/";
if (areaId==null){
throw new RuntimeException("该城市找不到AreaId");
}
//拼接请求地址
String uri=REALWEATHER_URL+areaId+".html";
String res = HttpUtil.createGet(uri).timeout(10000).header("Referer", "http://www.weather.com.cn/").execute().body();
//替换数据不然会影响json的解析
String json = res.replace("var dataSK=", "");
return JSONUtil.parseObj(json);
}

运行结果如下:

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_servlet_30

对比天气网看数据:

猿创征文|【手把手教你】如何获取中国天气网,获取想要城市的天气-图文并茂-分析代码_数据_31

🚀城市当天天气获取:

        这个就给你动手去完成吧,看的在多也没有自己去按照文章思路去分享一遍,这样自己也可以理解,真的就是看再多不如自己敲一遍来的深刻。特别是初学者一定会有很大的帮助。

🏆总结:

       看完这篇文章对于初学者来说,会有些困难,可能你看到后面去,你就不知道我在写些什么,问题不大,看不懂是因为没有理解我为什么要怎么做,你们可以带着自己的疑问去尝试分析一下,可能我这个方案也不是最佳的,但是可以通过需求去分析得到自己需要的结果,使用什么方法不重要,重要的是在这个过程中你收获了什么,你只看到我分析的过程中比较流畅,其实在我不了解,没去研究的情况下大部分的时间是花在分析上,知道原理之后就会明白自己需要如何写代码。
       这篇文章我也是断断续续的写了好几天,可能看到或读的人可能不多,那么我为什么要坚持写,写作的目的不是为了可以得到多少荣誉,更多的是为了自己在未来的路上走的更远,锻炼自己的思维能力,没有人天生就是笨的,只要你肯付出,加倍的付出你总能在某天感谢之前勤奋的自己,共勉

🍥结束:

    到这里分析城市天气到这里就完成了,后续代码会发布​​gitee​​上,如果对你有帮助,一键三连,一起加油!!!