天气API强势对接

2023-08-03 13:43:18

🤵‍♂️ 个人主页:@香菜的个人主页,加 ischongxin ,备注csdn

✍🏻作者简介:csdn 认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主

🐋 希望大家多多支持,我们一起进步!😄

如果文章对你有帮助的话,

欢迎评论 💬点赞👍🏻 收藏 📂加关注+

目录

前言:

墨迹天气数据接口

1、找到目标网页

2、获取城市id

3、试图爬取网页

4、获取网页的技术方案

5、分析网页获取数据

接口对接实现

总结

前言:

最近在做天气的接口对接,从最初的需求要街道级的数据,后来到区级别的,导致最终的技术方案也不同。

区级别的数据选择的是中国天气网的API接口,这个是收费的接口,调研的时候使用了试用数据集,等到项目真正想要购买的时候发现数据集已经失效了,而且在电话沟通的时候对方需要发邮件进行沟通,咨询价格接口什么也不说,沟通受阻,交给了商务同学去沟通,没下文了

在后来需求进行了变更,天气状况只要到区级别就行了,所以有了新的方案,一个选择是使用和风天气的免费API,对于我们来说够用,一个是直接在线爬取。

和风天气的API需要注册,文档地址:实时天气 for API | 和风天气开发服务,这个接口使用起来还挺方便,后续准备接入。

墨迹天气是打算直接获取,也是这次的方案,无视规则,而且我们30分钟爬取一次。今天也就写下墨迹天气的爬取

墨迹天气数据接口

1、找到目标网页

地址:墨迹天气:每日天气预报

分析下url ,这里主要只有一个参数cityId,这个编码如何获取呐?

2、获取城市id

通过下面网页上的地址:墨迹天气:城市搜索

输入你想要查询到地方,然后查询,在新的网页上会有新城市的id,

我猜官方应该也提供了类似的列表和接口,但是因为我们只需要苏州市几个区的数据,就懒得去找了,直接使用最笨的方法

获取的编码如下

# 苏州市,相城区,吴江区,姑苏区, 吴中区, 虎丘区 ,张家港,常熟市 
city: 1093,284853,1103, 284854,1098, 284852,1101, 1100

3、试图爬取网页

当前获取苏州市的天气状况

目标网页: 墨迹天气:每日天气预报

获取的数据如下左图,F12 之后可以看到对应的位置

这次的目标数据主要有三部分:

  • 天气和温度,也就是上图的最上面一列
  • 天气详细状况,上图的风向,风级别,湿度,体感温度,空气质量等
  • 预警信息,当前这个网页没显示,也就是实时天气更新时间上面空白部分,也是我们这次获取的重点信息。

4、获取网页的技术方案

在pom.xml中加入jsoup

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>

写个main函数获取数据

 public static ArrayList<String> getTitles(String url) throws IOException {
        //获取请求连接
        Connection con = Jsoup.connect(url);
        //请求头设置,特别是cookie设置
        con.header("Accept", "text/html, application/xhtml+xml, */*");
        con.header("Content-Type", "application/x-www-form-urlencoded");
        con.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36");
        con.header("accept-encoding", "gzip, deflate, br");
        //发送请求
        Document doc  =con.method(Connection.Method.GET).get();
        System.out.println(doc.toString());
        String indexTempNum = doc.getElementById("indexTempNum").text();
        return null;
    }
    public static void main(String[] args) throws IOException {
        String url = "https://html5.moji.com/tpd/mojiweather_pc/index.html?cityid=1100";
        ArrayList<String> titles = getTitles(url);
        System.out.println();
    }

在获取之后可以看到获取不到数据,只能看到占位符,真实的数据并没有

5、分析网页获取数据

F12 之后看看到网页加载了很多的数据

0

也不知道哪里获取的数据的,每个请求到点下,看下服务器的响应,功夫不负苦心人,在一番扒拉之后看到了main.js

爬取Jsoup -->爬取不到数据

 

0

从上图可以看到有所有的接口,在搜索之后也看到了请求的结构体。不得不说官方还是蛮实在的。

接口对接实现

这里主要是获取天气和预警信息,预报信息不需要。

预警信息数据和天气信息的数据就不贴出来了,等会会把源码上传

package com.tyjt.ccpweather.service;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.tyjt.ccpweather.po.AlertPO;
import com.tyjt.ccpweather.po.WeatherPO;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class WeatherUtil {


    public static WeatherPO queryWeather(Integer cityId) {
        WeatherPO build = null;
        try {
            Map<String, Object> paramMap = new HashMap<>();
            String url = "https://h5ctywhr.api.moji.com/weatherDetail";
            paramMap.put("cityId", cityId);
            paramMap.put("cityType", 0);
            String jsonString = JSON.toJSONString(paramMap);
            String result = HttpUtil.post(url, jsonString);
            JSONObject jsonObject = JSON.parseObject(result);
            if (!"0".equals(jsonObject.get("code").toString())) {
                return null;
            }
            String aqiDesc = jsonObject.getJSONObject("aqi").get("desc").toString();
            Integer aqiValue = jsonObject.getJSONObject("aqi").getInteger("value");
            JSONObject condition = jsonObject.getJSONObject("condition");

            Integer temp = condition.getInteger("temp");
            Integer realFeel = condition.getInteger("realFeel");
            Integer humidity = condition.getInteger("humidity");
            String windDir = condition.getString("windDir");
            Integer windLevel = condition.getInteger("windLevel");
            String weather = condition.getString("weather");
            String tips = condition.getString("tips");

            build = WeatherPO.builder().aqiDesc(aqiDesc)
                    .aqiValue(aqiValue)
                    .temp(temp)
                    .realFeel(realFeel)
                    .humidity(humidity)
                    .windDir(windDir)
                    .windLevel(windLevel)
                    .weather(weather)
                    .tips(tips)
                    .build();
        } catch (Exception e) {
            log.error("获取天气失败 ! cityId {}", cityId);
            log.error("", e);
        }

        return build;
    }

    public static List<AlertPO> queryAlert(Integer cityId) {
        try {
            Map<String, Object> paramMap = new HashMap<>();
            String url = "https://h5ctywhr.api.moji.com/weatherthird/alert";
            paramMap.put("cityId", cityId);
            String jsonString = JSON.toJSONString(paramMap);
            String result = HttpUtil.post(url, jsonString);
            JSONObject jsonObject = JSON.parseObject(result);

            List<AlertPO> resultList = new ArrayList<>();
            JSONArray alert = jsonObject.getJSONArray("alert");
            if (alert == null) {
                return null;
            }
            for (Object o : alert) {
                JSONObject item = (JSONObject) o;
                AlertPO build = AlertPO.builder()
                        .alertType(item.getInteger("alertTypeId"))
                        .level(item.getInteger("level"))
                        .content(item.getString("content"))
                        .publishTime(item.getLong("publishTime"))
                        .reliveTime(item.getLong("reliveTime"))
                        .publishSector(item.getString("publishSector"))
                        .name(item.getString("name"))
                        .build();
                resultList.add(build);
            }
            return resultList;
        } catch (Exception e) {
            log.error("获取预警信息失败 ! cityId {}", cityId);
            log.error("", e);
        }
        return null;
    }

    public static void main(String[] args) {
        queryAlert(2543);
    }
}

整个项目还有一些其他的细节,就不展示,这里直接贴出来下载地址

总结

整个实现过程还是花了不少时间,也学会了使用jsoup,这个包还是挺好用的。后面可以研究下

这里的接口也只选用了自己需要的一部分,后续可以根据不同项目要求,获取不同的天气

源码下载地址:https://download.csdn.net/download/perfect2011/88058335


 

 
本书主要以 Java 虚拟机的基本特性及运行原理为中心,深入浅出地分析 JVM 的组成结构和底层实现,介绍了很多性能调优的方案和工具的使用方法。最后还扩展介绍了 JMM 内存模型的实现原理和 Java 编译器的优化机制,让读者不仅可以学习 JVM 的核心技术知识,还能夯实 JVM 调优及代码优化的技术功底。

本书适合已具有一定 Java 编程基础的开发人员、项目经理、架构师及性能调优工程师参考阅读,同时,本书还可以作为广大职业院校、计算机培训班相关专业的教学参考用书。

京东购买链接:https://item.jd.com/13762401.html
 

更多推荐

✽js的快速入门5 window对象

BOM浏览器对象模型:是规范浏览器对js语言的支持(js调用浏览器本身功能)BOM的具体实现是window对象window对象使用1.不用new直接进行使用即可,类似Math的使用方式,window关键字可以省略不写window.document等等2.框体方法<!DOCTYPEhtml><htmllang="en">

vue中的 render 和 h() 详解

vue中的render和h()详解当使用Vue.js进行前端开发时,理解和掌握"render"函数和"h()"函数是非常重要的,因为它们是Vue组件的核心构建和渲染部分render和h()是在Vue.js中常用的两个概念,它们通常用于创建和渲染Vue组件。什么是"render"函数?"render"函数是Vue组件的一

Vue系列之入门篇

前言:目录一,关于Vue的简介1.什么是Vue?2.使用Vue框架的好处?3.库和框架的区别:4.MVVM的介绍5.Vue的入门案例二,Vue的生命周期一,关于Vue的简介1.什么是Vue?Vue是一个构建用户界面(UI)的渐进式JavaScript框架2.使用Vue框架的好处?简单易学:Vue的API设计简洁,易于理

(一)探索随机变量及其分布:概率世界的魔法

文章目录🍋引言🍋什么是随机变量?🍋离散随机变量🍋连续随机变量🍋随机变量的概率分布🍋离散概率分布🍋0-1分布(Bernoulli分布)🍋二项分布(Binomial分布)🍋泊松分布(Poisson分布)🍋几何分布(Geometric分布)🍋连续概率分布🍋均匀分布(UniformDistributio

基于Java+微信小程序实现《微信阅读平台》

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

软件定义世界,工程引领未来——中山大学软件工程学院 软件工程导论大作业

目录软件工程,理解加深个人困惑软件与软件工程的定义学习思路的启发软件危机的认识及思考软件测试的初步认识科技前沿,守正创新代码有智能,教育有情怀深入浅出,引人入胜再接再厉,未来可期“软件定义世界”是软工人的响亮口号,“工程引领未来”是我在上完导论课后的总结与思考。软件工程导论课作为软件工程学院开设的特色课程以及专业必修课

03、JSP核心技术

1JSP的概述(熟悉)1.1JSP的概念JSP是JavaServerPages的简称,跟Servlet一样可以动态生成HTML响应,JSP文件命名为xxx.jsp。与Servlet不同,JSP文件以HTML标记为主,然后内嵌Java代码段,用于处理动态内容。1.2JSP的示例1.3JSP与Servlet的关系2JSP的

设计模式之模板模式

文章目录豆浆制作问题模板方法模式基本介绍模板方法模式原理类图对原理类图的说明-即(模板方法模式的角色及职责)模板方法模式解决豆浆制作问题模板方法模式的钩子方法模板方法模式的注意事项和细节豆浆制作问题编写制作豆浆的程序,说明如下:制作豆浆的流程选材—>添加配料—>浸泡—>放到豆浆机打碎通过添加不同的配料,可以制作出不同口

强化学习从基础到进阶-案例与实践[6]:演员-评论员算法(advantage actor-critic,A2C),异步A2C、与生成对抗网络的联系等详解

【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现专栏详细介绍:【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现对于深度强化学习这块规划为:基础单智能算法教学(g

【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka

作者简介前言博主之前写过一个完整的MQ系列,包含RabbitMQ、RocketMQ、Kafka,从安装使用到底层机制、原理。专栏地址:https://blog.csdn.net/joker_zjn/category_12142400.html?spm=1001.2014.3001.5482本文是该系列的清单综述,会拉通

Kafka实现高性能消息队列分析

ApacheKafka是一款开源的、分布式的、高吞吐量的流平台。它被广泛用于实时数据流的处理,包括实时流分析、实时日志处理、实时事件处理等。Kafka的主要设计目标是高吞吐量、可扩展性、容错性和持久性。在本篇文章中,我们将深入探讨Kafka如何实现高性能消息队列,包括服务端和客户端的架构,以及关键的设计和优化技术,如服

热文推荐