Browse Source

增加路线爬虫

Pchen. 3 months ago
parent
commit
fd8f819c90
1 changed files with 167 additions and 0 deletions
  1. 167 0
      getPathData.js

+ 167 - 0
getPathData.js

@@ -0,0 +1,167 @@
+const axios = require('axios')
+const db = require('./plugin/DataBase/db')
+
+const API_URL = 'http://222.178.152.79:100/api_v1/getSportRecord'
+
+// ===== 账号组成 =====
+let part1 = '23'
+let part2 = 993 // 第二部分
+let part3 = 1   // 第三部分
+let part4 = 1   // 第四部分
+
+// ===== 最大范围(可自行调整)=====
+const MAX_P3 = 20
+const MAX_P4 = 90
+
+// ===== 南泉校区 =====
+const nq = [106.594871,29.421079]
+// ===== 双桥校区 =====
+const sq = [105.778790,29.512079]
+
+/**
+ * 计算两点经纬度之间的距离(单位:米)
+ * @param {[number, number]} p1 [经度, 纬度]
+ * @param {[number, number]} p2 [经度, 纬度]
+ * @returns {number} 距离(米,浮点数)
+ */
+function calcDistance(p1, p2) {
+  const [lng1, lat1] = p1
+  const [lng2, lat2] = p2
+
+  console.log(`计算距离,点1: (${lat1}, ${lng1}),点2: (${lat2}, ${lng2})`)
+
+  const toRad = d => d * Math.PI / 180
+
+  const R = 6378137 // 地球半径(米,WGS84)
+
+  const φ1 = toRad(lat1)
+  const φ2 = toRad(lat2)
+  const Δφ = toRad(lat2 - lat1)
+  const Δλ = toRad(lng2 - lng1)
+
+  const a =
+    Math.sin(Δφ / 2) ** 2 +
+    Math.cos(φ1) * Math.cos(φ2) *
+    Math.sin(Δλ / 2) ** 2
+
+  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
+
+  return R * c
+}
+
+// ===== 工具函数 =====
+const pad2 = n => String(n).padStart(2, '0')
+
+function genAccount() {
+    return `${part1}${part2}${pad2(part3)}${pad2(part4)}`
+}
+
+function parsePathLine(pathLine) {
+  return pathLine.split(';').map(p => {
+    const [lat, lng] = p.split(',').map(Number);
+    return [lng, lat];
+  });
+}
+
+// ===== 进位逻辑 =====
+
+// 无数据:第三部分进位,必要时第二部分进位
+function advanceOnNoData() {
+    part3++
+
+    if (part3 > MAX_P3) {
+        part3 = 1
+        part2++
+        console.log('>>> 第三部分耗尽,第二部分进位为:', part2)
+    }
+
+    part4 = 1
+}
+
+// 有数据:第四部分进位
+function advanceOnHasData() {
+    part4++
+
+    if (part4 > MAX_P4) {
+        part4 = 1
+        part3++
+
+        if (part3 > MAX_P3) {
+            part3 = 1
+            part2++
+            console.log('>>> 第四、三部分耗尽,第二部分进位为:', part2)
+        }
+    }
+}
+
+// ===== 单次请求 =====
+async function fetchOnce() {
+    const account = genAccount()
+    console.log('\n请求 account:', account)
+
+    const res = await axios.post(
+        API_URL,
+        `account=${account}&startdate=2020-01-01&enddate=2025-12-31`,
+        { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
+    )
+
+    const data = res.data
+
+    // ❌ 无数据
+    if (!data || !data.data || data.data.length === 0) {
+        console.log('无 data,执行进位')
+        advanceOnNoData()
+        return
+    }
+
+    // ✅ 有数据
+    for (let index = 0; index < data.data.length; index++) {
+        const item = data.data[index]
+
+        if (item.status !== 1) continue
+
+        const coords = parsePathLine(item.pathLine)
+        const pathLineJson = JSON.stringify(coords)
+
+        const sq_distance = calcDistance(sq, coords[0])
+        const nq_distance = calcDistance(nq, coords[0])
+        console.log(`双桥校区距离起点: ${sq_distance.toFixed(2)} 米,南泉校区距离起点: ${nq_distance.toFixed(2)} 米`)
+
+        const run_zone_name = sq_distance < nq_distance ? '重庆工程学院双桥校区' : '重庆工程学院南泉校区'
+
+        const sql = `
+            INSERT INTO path_data
+            (distance, time, calorie, speed, data, run_zone_name)
+            VALUES (?, ?, ?, ?, ?, ?)
+        `
+
+        await db.query(sql, [
+            item.distance,
+            item.duration,
+            item.calorie,
+            item.distribution,
+            pathLineJson,
+            run_zone_name
+        ])
+
+        console.log(
+            `已保存到数据库。距离:${item.distance} 米,时长:${item.duration} 秒,路径点:${coords.length} 个`
+        )
+    }
+
+    advanceOnHasData()
+}
+
+// ===== 主循环 =====
+(async function start() {
+    while (true) {
+        try {
+            await fetchOnce()
+        } catch (e) {
+            console.error('请求异常:', e.message)
+        }
+
+        // 控制请求频率
+        await new Promise(r => setTimeout(r, 200))
+    }
+})()