From 0d7e254cf4a0981b6b4cbc9d68a1503d9c1b318f Mon Sep 17 00:00:00 2001 From: hbk01 <3243430237@qq.com> Date: Mon, 12 May 2025 21:49:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++ package.json | 21 ++++++++ src/index.html | 82 +++++++++++++++++++++++++++++++ src/index.js | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 src/index.html create mode 100644 src/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adae22e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +data/ + +package-lock.json \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..1df9edf --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "oil", + "version": "1.0.0", + "description": "查询当前油价", + "keywords": [ + "oil" + ], + "license": "GPL-3.0-or-later", + "author": "hbk01", + "type": "module", + "main": "index.js", + "scripts": { + "test": "nodemon ./src/index.js" + }, + "dependencies": { + "axios": "^1.9.0", + "cheerio": "^1.0.0", + "express": "^5.1.0", + "nodemon": "^3.1.10" + } +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..ce979fb --- /dev/null +++ b/src/index.html @@ -0,0 +1,82 @@ + + + + + + + 油价 + + + + + + + +
+ + + + + + + + + + + +
地区92#95# 0#
+ +
+

+ 数据来源:小熊油耗
+ 更新时间: +

+ 免责声明:本数据仅供参考,具体油价请以当地加油站实际价格为准。 +

+

+
+ + + \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..ba8bf9a --- /dev/null +++ b/src/index.js @@ -0,0 +1,127 @@ +import axios from 'axios' +import * as cheerio from 'cheerio' +import express from 'express' +import path from 'path' +import fs from 'fs' + +const app = express() +const __dirname = path.resolve() + +app.get('/', (req, res) => { + res.sendFile(path.join(__dirname, 'src', 'index.html')) +}) + +app.get('/query', async (req, res) => { + let { name, force } = req.query + if (force == undefined) { + force = false + } + const data = getOilPriceJson(force) + if (name) { + const filteredData = data.filter(item => item.name.includes(name)) + res.json(filteredData) + } else { + res.json(data) + } +}) + +app.listen(1933, () => { + console.log('Server is running on port 1933') +}); + +// 获取油价数据,若本地数据存在则读取本地数据,否则请求网络数据,并保存到本地以供后续使用。 +// force 参数用于强制刷新本地数据 +const getOilPriceJson = (force) => { + const filename = new Date().format().split("T")[0].replaceAll("-", "").concat(".json") + const filepath = path.join(__dirname, "data", filename) + if (fs.existsSync(filepath) && !force) { + const data = fs.readFileSync(filepath, "utf-8") + return JSON.parse(data) + } else { + // 如果目录不存在,则创建目录 + if (!fs.existsSync(path.join(__dirname, "data"))) { + fs.mkdirSync(path.join(__dirname, "data"), { recursive: true }) + } + // 如果文件存在,则需要删除文件 + if (fs.existsSync(filepath)) { + fs.rmSync(filepath) + } + + getOilPrice((data) => { + data.push({ + name: "更新时间", + time: new Date().format() + }) + fs.writeFileSync(filepath, JSON.stringify(data), "utf-8") + }) + } +} + +const getOilPrice = async (callback) => { + const url = "https://www.xiaoxiongyouhao.com/fprice/" + let data = [] + const response = await axios.get(url) + const $ = cheerio.load(response.data) + + // 解析 html 页面 + $("table").each((i, elem) => { + const table = $(elem) + const rows = table.find("tr") + rows.each((j, row) => { + const cells = $(row).find("td") + let rowData = {} + cells.each((k, cell) => { + switch (k) { + case 0: + rowData["name"] = rename($(cell).text()) + break + case 1: + rowData["92#"] = $(cell).text() + break + case 2: + rowData["95#"] = $(cell).text() + break + case 3: + rowData["0#"] = $(cell).text() + break + default: + rowData["other"] = $(cell).text() + break + } + }) + // 过滤掉空行 + if (Object.keys(rowData).length > 0) { + data.push(rowData); + } + }) + }) + callback(data) +} + +// 统一地区名称 +const rename = (name) => { + name = name.replace("省", "") + name = name.replace("市", "") + name = name.replace("内蒙古自治区", "内蒙古") + name = name.replace("广西壮族自治区", "广西") + name = name.replace("西藏自治区", "西藏") + name = name.replace("宁夏回族自治区", "宁夏") + name = name.replace("新疆维吾尔自治区", "新疆") + name = name.replace("香港特别行政区", "香港") + name = name.replace("澳门特别行政区", "澳门") + return name +} + +// 为 Date 创建日期格式化方法 +Date.prototype.format = function () { + let fillZero = (num) => { + return num < 10 ? "0" + num : num + } + let year = fillZero(this.getFullYear()) + let month = fillZero(this.getMonth() + 1) + let day = fillZero(this.getDate()) + let hour = fillZero(this.getHours()) + let minute = fillZero(this.getMinutes()) + let second = fillZero(this.getSeconds()) + return `${year}-${month}-${day}T${hour}:${minute}:${second}` +}