基于MongoDB的气温数据可视化项目

本文是基于大数据方向MongoDB数据库的气温可视化项目,旨在让大家认识到MongDB数据库的使用,以及作为一个数据库该如何存储数据及取出数据,如何连接前后端,将数据展示出来。 涉及到的技术包含有Python爬虫、MongoDB的Java API,Flask框架、echarts可视化,作为一个练手小项目。

一、数据来源

编写一个爬虫程序从天气网站上爬取所需要的数据。这里爬取某市一年的天气。

爬取数据网址为:https://lishi.tianqi.com/huangshi.html,并且可以根据想要爬取的年份月份更改网址。

根据网站源代码编写爬取程序,需要注意的是,由于MongoDB的文档数据以BSON(JSON格式的一种拓展)格式存储,可以存储列表、key-value以及层次结构更加复杂的文档。我们需要将爬取到的数据添加列表中并转换成json数据文件存储,以便后续将数据存入数据库中:

爬虫代码

import requests  # 模拟浏览器进行网络请求
from lxml import etree  # 进行数据预处理
import json


def getWeather(uurl):
    weather_info = []  # 新建一个列表,将爬取的每月数据放进去
    # 请求头信息:浏览器版本型号,接收数据的编码格式
    headers = {
        'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 '
            'Safari/537.36 Edg/118.0.2088.76'
    }
    # 请求
    resp = requests.get(uurl, headers=headers)
    # 数据预处理
    resp_html = etree.HTML(resp.text)
    # xpath提取所有数据
    resp_list = resp_html.xpath("//ul[@class='thrui']/li")
    # for循环迭代遍历
    for li in resp_list:
        day_weather_info = {'data_time': li.xpath("./div[1]/text()")[0].split(' ')[0]}
        # 日期
        # 最高气温(包含摄氏度符号)
        high = li.xpath("./div[2]/text()")[0]
        day_weather_info['high'] = high[:high.find('℃')]
        # 最低气温
        low = li.xpath("./div[3]/text()")[0]
        day_weather_info['low'] = low[:low.find('℃')]
        # 天气
        day_weather_info['weather'] = li.xpath("./div[4]/text()")[0]
        weather_info.append(day_weather_info)
    return weather_info


weathers = []

# for循环生成有顺序的1-12
for month in range(1, 13):
    # 获取某一月的天气
    # 三元表达式
    weather_time = '2023' + ('0' + str(month) if month < 10 else str(month))
    print(weather_time)
    url = f'https://lishi.tianqi.com/huangshi/{weather_time}.html'
    weather = getWeather(url)
    weathers.append(weather)

# 将列表数据存储为JSON文件
with open('month_data.json', 'w') as file:
    json.dump(weathers, file, indent=4)
print(weathers)

将爬取出来的数据转成json文件后,存储格式如下:

基于MongoDB的气温数据可视化项目_第1张图片

二、启动MongoDB数据库

环境准备(基于Hadoop集群的相关操作):

启动:myhadoop.sh start

启动:MongoDB

$/opt/module/mongodb-5.0.5/bin/mongod -f

/opt/module/mongodb-5.0.5/conf/mongo.conf

$ /opt/module/mongodb-5.0.5/bin/mongo --host 127.0.0.1 --port 27017

注意:以上启动是基于Hadoop集群上的MongoDB操作,开启虚拟机,在xshell启动。

基于MongoDB的气温数据可视化项目_第2张图片

三、将数据存储到数据库

使用爬虫获取的数据满足大数据分析的基本条件,本次实验使用的气温数据需要利用Java API插入到数据库中。

3.1 idea项目初始化

创建一个maven项目,idea项目结构如下:

基于MongoDB的气温数据可视化项目_第3张图片

3.2 向pom.xml文件中导入依赖



    4.0.0

    org.example
    mongodbDemo
    1.0-SNAPSHOT
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    7
                    7
                
            
        
    

    
        
        
            junit
            junit
            4.12
        
        
        
            org.mongodb
            mongo-java-driver
            3.12.1
        

        
            com.googlecode.json-simple
            json-simple
            1.1.1
        
    

3.3 创建MongoDBUtil工具类

其中封装了MongoDB工具类通过连接池获取对象访问服务器的方法。

package com.sjy.util;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
/**
 * 封装MongoDB工具类通过连接池获取对象访问服务器
 */
public class MongoDBUtil {
    private static MongoClient mongoClient = null;
    private static MongoClientOptions.Builder builder = null;
    private static MongoClientOptions options = null;
    //服务器IP
    private static String HOST = "192.168.10.102";
    //端口
    private static int PORT = 27017;
    //用户名
    private static String USER = "root";
    //密码
    private static String PASSWORD = "111111";
    //与目标数据库可以建立的最大链接数
    private static int CONNECTIONS_PERHOST = 100;
    //这个参数是跟connectionPerHost配套的,当连接超过connectionPerHost的时候,需要建立新的连接
    //连接请求会被阻塞,这个参数就代表允许阻塞请求的最大值,超过这个值之后的请求都会报错
    private static int THREADS_ALLOWED_TO_BLOCK_FOR_CONNECTION_MULTIPLIER = 100;
    //与数据库建立链接的超过时间
    private static int CONNECT_TIMEOUT = 1000 * 60 * 20;
    //一个线程成功获取到一个可用数据库之前的最大等待时间
    private static int MAX_WAILTIME = 100 * 60 * 5;
    //执行IO操作的超过时间,默认为0,代表不超时
    private static int SOCKE_TIMEOUT = 0;

    /**
     * 初始化连接池
     */
    static {
        try {
            builder = new MongoClientOptions.Builder();
//            builder.set
            builder.connectionsPerHost(CONNECTIONS_PERHOST);
            builder.threadsAllowedToBlockForConnectionMultiplier(THREADS_ALLOWED_TO_BLOCK_FOR_CONNECTION_MULTIPLIER);
            builder.connectTimeout(CONNECT_TIMEOUT);
            builder.maxWaitTime(MAX_WAILTIME);
            builder.socketTimeout(SOCKE_TIMEOUT);
            options = builder.build();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过连接池获取连接对象并操作服务器
     */
    public static MongoClient getMongoClient() {
        if (mongoClient != null) {
            return mongoClient;
        }
        try {
            mongoClient = new MongoClient(new ServerAddress(HOST, PORT), options);
            return mongoClient;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 释放资源
     */
    public static void close(MongoClient mongoClient) {
        if (mongoClient != null) {
            mongoClient.close();
        }
    }
}

3.4 Java API操作MongoDB

首先创建一个MongoClient实例来连接到本地运行在默认端口上的MongoDB服务器。接着,我们获取目标数据库和集合的引用。

接下来,创建一个新的Document对象,并将JSONObject中的所有键值对添加到这个Document对象中。最后,将这个Document对象插入到MongoDB集合中。这里的json文件就是上述爬虫程序爬取到的数据文件。

package com.sjy.mongodb;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.sjy.util.MongoDBUtil;
import org.bson.Document;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class WeatherTest {
    public static void main(String[] args) {
        // 连接到MongoDB服务器
        MongoClient mongoClient = MongoDBUtil.getMongoClient();
        // 获取数据库和集合实例
        MongoDatabase database = mongoClient.getDatabase("my_database");
        MongoCollection collection = database.getCollection("weather");
        // 从JSON文件中读取数据
        List documents = new ArrayList<>();
        JSONParser parser = new JSONParser();
        try (FileReader reader = new FileReader("d:/data.json")) {
            Object obj = parser.parse(reader);

            JSONArray jsonArray = (JSONArray) obj;
            for (Object o : jsonArray) {
                JSONObject jsonObject = (JSONObject) o;
                String id = UUID.randomUUID().toString();
                Document document = new Document("_id", id)
                        .append("data_time", jsonObject.get("data_time"))
                        .append("high", jsonObject.get("high"))
                        .append("low", jsonObject.get("low"))
                        .append("weather", jsonObject.get("weather"));
                documents.add(document);
            }

        } catch (IOException | ParseException e) {
            System.err.println("Error reading data from file: " + e.getMessage());
        }
        // 执行批量插入
        collection.insertMany(documents);
        FindIterable weatherDo = collection.find();
        for (Document document : weatherDo) {
            System.out.println(document.toJson());
        }
        // 关闭MongoClient连接
        mongoClient.close();
    }
}

最后测试数据是否插入成功

四、项目可视化

为了更好地理解和解释分析结果,我们使用Echarts创建了一系列图表,包括柱状图、饼图。这些可视化工具使我们能够直观地看到数据的模式和趋势。

flask项目结构如下:

基于MongoDB的气温数据可视化项目_第4张图片

4.1 可视化后端实现

本次项目可视化我使用了Python的flask框架作为后端。Flask是一个微框架,它比其他如Django等大型框架更简洁、轻巧。这意味着我可以快速搭建一个小型应用,并且在不引入过多额外依赖的情况下专注于核心功能——数据可视化。Flask默认集成了Jinja2模板引擎,它可以方便地将数据插入到HTML页面中,这对于动态生成包含可视化的网页非常有用。

引入项目所需库,连接MongoDB数据库,执行find()方法,获取所需要的数据,并将需要的数据添加到列表中发送给前端。本次实验需要的数据是日期、该日最高温度和最低温度。

from flask import Flask, render_template, request
# render_template作用是把html网页渲染完然后扔给服务器
import pymongo
import json
# 创建一个app
app = Flask(__name__)
# 连接到MongoDB数据库
client = pymongo.MongoClient("mongodb://192.168.10.102:27017/")
# 选择数据库
db = client["my_database"]
# 选择集合
collection = db["weather"]
# 创建游标对象
cursor = collection.find()
data_time = []
high = []
low = []
weather = {}

for document in cursor:
    print(document)
    data_time.append(document.get('data_time')[5:])
    high.append(document.get('high'))
    low.append(document.get('low'))

data = {
    'data_time': data_time,
    'high': high,
    'low': low
}

@app.route("/")
def show():
    return render_template("show.html", data=data)


# 运行这个app
if __name__ == '__main__':
    app.run()

4.2 可视化前端实现

本次项目可视化我使用ECharts 库,在前端代码中引入ECharts标签 ECharts 是一个由百度商业前端数据可视化团队开发的开源数据可视化库。它基于 JavaScript,能够创建丰富的图表和图形,包括折线图、柱状图、饼图、地图等,用于展示和分析数据。并且ECharts 有一个清晰的 API 和详细的文档,开发者可以快速上手并创建出复杂的图表。

html代码,使用了echarts示例中的折线图,可以更清晰的展现某市上一个月的气温变化。




    
    Title
    
    


    

4.3 可视化效果图

总结

本实验的主要目标是使用MongoDB数据库存储黄石市上一个月的气温数据,并通过可视化的手段展示结果。我们首先使用Python爬虫从天气网站上抓取了一年内的所有气温数据。然后,将数据转存为json格式,确保后续使用Java API存储到MongoDB数据库中数据文件的解析性。最后使用flask框架连接MongoDB数据库,查询出存储的所有气温数据,再过滤出我们需要的数据。

你可能感兴趣的:(mongodb,信息可视化,数据库,flask,python,maven)