如何自己动手制作一个地震列表?

yasjun 发布于 2025-04-17 846 次阅读


因为最近一些事件可能觉得自己时日不多了(bus),还是要类似于日本那边的防灾月历的形式公开一下部分内容的制作细节。
如果你需要查看日本每年都会举办的防灾软件开发月,请点击下方链接(2024年防灾应用开发月历):
https://adventar.org/calendars/9939

一、数据源

当然现在数据源很多,这里不再赘述(避免出现拉踩嫌疑)。
当然,这里建议自建API,避免因为在线服务/第三方服务突发崩溃导致生产内容不可用。
这里给出最简单的台网地震列表API制作(Python,完成于2022年1月,目前已不使用,在此处仅为示例)

import json
from requests_html import HTMLSession
import time,sched
import requests


def ceicget():
    while True:
        # 获取请求对象
        session = HTMLSession()

        url = 'http://news.ceic.ac.cn'
        requests.packages.urllib3.disable_warnings()
        r = session.get(url,verify=False,headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Edg/93.0.961.52'})
        r_code = r.html.find('body>div>div.main>div>div.left>#news>table>tr')
        cnquake={}
        cnquake1 = (f'{r_code[1].full_text}')
        list1 = cnquake1.split()
        cnquake2 = (f'{r_code[2].full_text}')
        list2 = cnquake2.split()
        cnquake3 = (f'{r_code[3].full_text}')
        list3 = cnquake3.split()
        cnquake4 = (f'{r_code[4].full_text}')
        list4 = cnquake4.split()
        cnquake5 = (f'{r_code[5].full_text}')
        list5 = cnquake5.split()
        cnquake6 = (f'{r_code[6].full_text}')
        list6 = cnquake6.split()
        cnquake7 = (f'{r_code[7].full_text}')
        list7 = cnquake7.split()
        # print(cnquake1)
        # cnquake = (f'{r_code[1].full_text}')
        eqinfo = {}
        data = json.loads(json.dumps(eqinfo))


        data['eq1'] = {'M':list1[0],'date':list1[1],'time':list1[2],'lat':list1[3],'lon':list1[4],'depth':list1[5],'epicenter':list1[6]}
        data['eq2'] = {'M':list2[0],'date':list2[1],'time':list2[2],'lat':list2[3],'lon':list2[4],'depth':list2[5],'epicenter':list2[6]}
        data['eq3'] = {'M':list3[0],'date':list3[1],'time':list3[2],'lat':list3[3],'lon':list3[4],'depth':list3[5],'epicenter':list3[6]}
        data['eq4'] = {'M':list4[0],'date':list4[1],'time':list4[2],'lat':list4[3],'lon':list4[4],'depth':list4[5],'epicenter':list4[6]}
        data['eq5'] = {'M':list5[0],'date':list5[1],'time':list5[2],'lat':list5[3],'lon':list5[4],'depth':list5[5],'epicenter':list5[6]}
        data['eq6'] = {'M':list6[0],'date':list6[1],'time':list6[2],'lat':list6[3],'lon':list6[4],'depth':list6[5],'epicenter':list6[6]}
        data['eq7'] = {'M':list7[0],'date':list7[1],'time':list7[2],'lat':list7[3],'lon':list7[4],'depth':list7[5],'epicenter':list7[6]}
        list = json.dumps(data, ensure_ascii=False)
        result=open('cenceqlist.json','w',encoding='utf-8-sig')
        result.write(list)
        result.close()
        time.sleep(35)
if __name__ == '__main__':
    ceicget()

在进行以上操作之后,会得到以下的json(此处仅为示例)

{"eq1": {"M": "3.1", "date": "2022-01-27", "time": "07:31:20", "lat": "41.87", "lon": "81.88", "depth": "15", "epicenter": "新疆阿克苏地区拜城县"}, "eq2": {"M": "3.8", "date": "2022-01-27", "time": "03:15:25", "lat": "37.77", "lon": "101.22", "depth": "11", "epicenter": "青海海北州门源县"}, "eq3": {"M": "3.1", "date": "2022-01-26", "time": "17:52:48", "lat": "45.36", "lon": "117.32", "depth": "15", "epicenter": "内蒙古锡林郭勒盟东乌珠穆沁旗"}, "eq4": {"M": "3.3", "date": "2022-01-26", "time": "15:33:02", "lat": "41.14", "lon": "83.73", "depth": "14", "epicenter": "新疆阿克苏地区库车市"}, "eq5": {"M": "4.3", "date": "2022-01-25", "time": "22:35:53", "lat": "24.64", "lon": "121.98", "depth": "46", "epicenter": "台湾宜兰县海域"}, "eq6": {"M": "3.7", "date": "2022-01-25", "time": "10:51:14", "lat": "29.00", "lon": "95.01", "depth": "15", "epicenter": "西藏林芝市墨脱县"}, "eq7": {"M": "5.9", "date": "2022-01-25", "time": "09:24:33", "lat": "-55.20", "lon": "-28.60", "depth": "10", "epicenter": "南桑威奇群岛"}}

(为什么是7条?原因是kiwi monitor就是七条

二、选择适合你的编程语言

在这里,可以使用任何的编程语言,这里使用html+JavaScript来简易编写(不包含css样式)。
你也可以选择用Java(JQuake,GlobalQuake等),
或者C系列(C,C#,C++)来制作适用于Windows的应用程序。(Kiwi monitor,KyoshinEewViewer,Quarog等)
H5可以使用electron和tauri等(基于Chromium)来实现全平台(Windows,macOS,Linux,Android,iOS等)。(ZeroQuake,CEIV,TREM等)

三、开始编写代码

如果你不会任何的编程语言,可以在百度/Google/Bing等搜索引擎进行搜索,也可以在bilibili/Youtube搜索相关编程语言的从0开始的教程;
如果你会其中一种/多种编程语言,那么这里只会完成大概框架搭建,在这里只是提供一个解决思路。

(2026编辑)
其实任意找一个AI就可以了 :)
大致你只需要说这些:

帮我用HTML/JavaScript/TypeScript/Python/C/C++/...做一个地震列表展示,这里是json数据:{粘贴你的数据json}

这里是我用gemini生成的结果:

地震信息实时列表

最新地震活动记录

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>地震信息实时列表</title>
    <style>
        :root {
            --bg-color: #f4f7f6;
            --card-bg: #ffffff;
            --primary-text: #333;
            --secondary-text: #666;
            --accent-color: #e74c3c;
        }

        body {
            font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
            background-color: var(--bg-color);
            color: var(--primary-text);
            display: flex;
            justify-content: center;
            padding: 40px 20px;
            margin: 0;
        }

        .container {
            width: 100%;
            max-width: 800px;
        }

        h2 {
            text-align: center;
            font-weight: 300;
            color: #2c3e50;
            margin-bottom: 30px;
        }

        .eq-list {
            display: flex;
            flex-direction: column;
            gap: 15px;
        }

        .eq-card {
            background: var(--card-bg);
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
            display: grid;
            grid-template-columns: 80px 1fr auto;
            align-items: center;
            transition: transform 0.2s;
        }

        .eq-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0,0,0,0.1);
        }

        .magnitude {
            font-size: 1.8rem;
            font-weight: bold;
            color: var(--accent-color);
            text-align: center;
            border-right: 2px solid #eee;
        }

        .info {
            padding-left: 20px;
        }

        .location {
            font-size: 1.1rem;
            font-weight: 600;
            margin-bottom: 5px;
        }

        .details {
            font-size: 0.85rem;
            color: var(--secondary-text);
        }

        .time-badge {
            text-align: right;
            font-size: 0.85rem;
            color: #999;
        }

        /* 震级越高颜色越深 */
        .m-high { color: #c0392b; }
        .m-mid { color: #f39c12; }
    </style>
</head>
<body>

<div class="container">
    <h2>最新地震活动记录</h2>
    <div id="list-container" class="eq-list">
        </div>
</div>

<script>
    const rawData = {"eq1": {"M": "3.1", "date": "2022-01-27", "time": "07:31:20", "lat": "41.87", "lon": "81.88", "depth": "15", "epicenter": "新疆阿克苏地区拜城县"}, "eq2": {"M": "3.8", "date": "2022-01-27", "time": "03:15:25", "lat": "37.77", "lon": "101.22", "depth": "11", "epicenter": "青海海北州门源县"}, "eq3": {"M": "3.1", "date": "2022-01-26", "time": "17:52:48", "lat": "45.36", "lon": "117.32", "depth": "15", "epicenter": "内蒙古锡林郭勒盟东乌珠穆沁旗"}, "eq4": {"M": "3.3", "date": "2022-01-26", "time": "15:33:02", "lat": "41.14", "lon": "83.73", "depth": "14", "epicenter": "新疆阿克苏地区库车市"}, "eq5": {"M": "4.3", "date": "2022-01-25", "time": "22:35:53", "lat": "24.64", "lon": "121.98", "depth": "46", "epicenter": "台湾宜兰县海域"}, "eq6": {"M": "3.7", "date": "2022-01-25", "time": "10:51:14", "lat": "29.00", "lon": "95.01", "depth": "15", "epicenter": "西藏林芝市墨脱县"}, "eq7": {"M": "5.9", "date": "2022-01-25", "time": "09:24:33", "lat": "-55.20", "lon": "-28.60", "depth": "10", "epicenter": "南桑威奇群岛"}};

    const container = document.getElementById('list-container');

    // 将对象转为数组并渲染
    Object.values(rawData).forEach(eq => {
        const card = document.createElement('div');
        card.className = 'eq-card';
        
        // 简单的震级样式判断
        const mClass = parseFloat(eq.M) >= 5 ? 'm-high' : (parseFloat(eq.M) >= 4 ? 'm-mid' : '');

        card.innerHTML = `
            <div class="magnitude ${mClass}">${eq.M}</div>
            <div class="info">
                <div class="location">${eq.epicenter}</div>
                <div class="details">
                    深度: ${eq.depth}km | 经度: ${eq.lon}° | 纬度: ${eq.lat}°
                </div>
            </div>
            <div class="time-badge">
                <div>${eq.date}</div>
                <div>${eq.time}</div>
            </div>
        `;
        container.appendChild(card);
    });
</script>

</body>
</html>

当然,如果用不了Gemini,也可以使用DeepSeek、文心、元宝、豆包、千问、小爱、通义灵码、ChatGPT、Grok、Claude、Kimi、Github Copilot、Microsoft Copilot、Cursor...