feat: 新增 虎扑 & 新浪网 & 新浪新闻

- 修复历史上的今天 #63
This commit is contained in:
imsyy
2024-06-25 13:47:40 +08:00
parent 6988df58f1
commit bf80a2e22c
25 changed files with 348 additions and 36 deletions

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "36kr",
title: "36氪",
type: "热榜",
parame: {
params: {
type: {
name: "热榜分类",
type: {

View File

@@ -11,7 +11,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "52pojie",
title: "吾爱破解",
type: "榜单",
parame: {
params: {
type: {
name: "榜单分类",
type: {

View File

@@ -12,7 +12,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
title: "AcFun",
type: "排行榜",
description: "AcFun是一家弹幕视频网站致力于为每一个人带来欢乐。",
parame: {
params: {
type: {
name: "频道",
type: {

View File

@@ -9,7 +9,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "baidu",
title: "百度",
type: "热搜榜",
parame: {
params: {
type: {
name: "热搜类别",
type: {

View File

@@ -12,7 +12,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
title: "哔哩哔哩",
type: "热门榜",
description: "你所热爱的,就是你的生活",
parame: {
params: {
type: {
name: "排行榜分区",
type: {

View File

@@ -18,14 +18,14 @@ export const handleRoute = async (_: undefined, noCache: boolean) => {
};
// 数据处理
const getNumbers = (text: string | undefined) => {
if (!text) return 10000000;
const getNumbers = (text: string | undefined): number => {
if (!text) return 0;
const regex = /\d+/;
const match = text.match(regex);
if (match) {
return Number(match[0]);
} else {
return 10000000;
return 0;
}
};
@@ -44,7 +44,8 @@ const getList = async (noCache: boolean) => {
const listData = listDom.toArray().map((item) => {
const dom = $(item);
const url = dom.find("a").attr("href") || undefined;
const score = dom.find(".rating_nums").text() ?? "0.0";
const scoreDom = dom.find(".rating_nums");
const score = scoreDom.length > 0 ? scoreDom.text() : "0.0";
return {
id: getNumbers(url),
title: `${score}${dom.find("a").attr("title")}`,

View File

@@ -33,7 +33,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "earthquake",
title: "中国地震台",
type: "地震速报",
parame: {
params: {
type: {
name: "速报分类",
type: {

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "genshin",
title: "原神",
type: "最新动态",
parame: {
params: {
type: {
name: "榜单分类",
type: {

View File

@@ -11,7 +11,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
title: "HelloGitHub",
type: "热门仓库",
description: "分享 GitHub 上有趣、入门级的开源项目",
parame: {
params: {
sort: {
name: "排行榜分区",
type: {

View File

@@ -6,14 +6,14 @@ import { getCurrentDateTime } from "../utils/getTime.js";
export const handleRoute = async (c: ListContext, noCache: boolean) => {
// 获取日期
const day = c.req.query("day") || getCurrentDateTime().day;
const month = c.req.query("month") || getCurrentDateTime().month;
const day = c.req.query("day") || getCurrentDateTime(true).day;
const month = c.req.query("month") || getCurrentDateTime(true).month;
const { fromCache, data, updateTime } = await getList({ month, day }, noCache);
const routeData: RouterData = {
name: "history",
title: "历史上的今天",
type: `${month}-${day}`,
parame: {
params: {
month: "月份",
day: "日期",
},

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "honkai",
title: "崩坏3",
type: "最新动态",
parame: {
params: {
type: {
name: "榜单分类",
type: {

View File

@@ -11,7 +11,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "hostloc",
title: "全球主机交流",
type: "榜单",
parame: {
params: {
type: {
name: "榜单分类",
type: {

51
src/routes/hupu.ts Normal file
View File

@@ -0,0 +1,51 @@
import type { RouterData, ListContext, Options } from "../types.js";
import type { RouterType } from "../router.types.js";
import { get } from "../utils/getData.js";
export const handleRoute = async (c: ListContext, noCache: boolean) => {
const type = c.req.query("type") || "1";
const { fromCache, data, updateTime } = await getList({ type }, noCache);
const routeData: RouterData = {
name: "hupu",
title: "虎扑",
type: "步行街热帖",
params: {
type: {
name: "榜单分类",
type: {
1: "主干道",
6: "恋爱区",
11: "校园区",
12: "历史区",
612: "摄影区",
},
},
},
link: "https://bbs.hupu.com/all-gambia",
total: data?.length || 0,
updateTime,
fromCache,
data,
};
return routeData;
};
const getList = async (options: Options, noCache: boolean) => {
const { type } = options;
const url = `https://m.hupu.com/api/v2/bbs/topicThreads?topicId=${type}&page=1`;
const result = await get({ url, noCache });
const list = result.data.data.topicThreads;
return {
fromCache: result.fromCache,
updateTime: result.updateTime,
data: list.map((v: RouterType["hupu"]) => ({
id: v.tid,
title: v.title,
author: v.username,
hot: v.replies,
timestamp: null,
url: `https://bbs.hupu.com/${v.tid}.html`,
mobileUrl: v.url,
})),
};
};

137
src/routes/sina-news.ts Normal file
View File

@@ -0,0 +1,137 @@
import type { RouterData, ListContext, Options } from "../types.js";
import type { RouterType } from "../router.types.js";
import { getTime, getCurrentDateTime } from "../utils/getTime.js";
import { get } from "../utils/getData.js";
// 榜单类别
const listType = {
"1": {
name: "总排行",
www: "news",
params: "www_www_all_suda_suda",
},
"2": {
name: "视频排行",
www: "news",
params: "video_news_all_by_vv",
},
"3": {
name: "图片排行",
www: "news",
params: "total_slide_suda",
},
"4": {
name: "国内新闻",
www: "news",
params: "news_china_suda",
},
"5": {
name: "国际新闻",
www: "news",
params: "news_world_suda",
},
"6": {
name: "社会新闻",
www: "news",
params: "news_society_suda",
},
"7": {
name: "体育新闻",
www: "sports",
params: "sports_suda",
},
"8": {
name: "财经新闻",
www: "finance",
params: "finance_0_suda",
},
"9": {
name: "娱乐新闻",
www: "ent",
params: "ent_suda",
},
"10": {
name: "科技新闻",
www: "tech",
params: "tech_news_suda",
},
"11": {
name: "军事新闻",
www: "news",
params: "news_mil_suda",
},
};
export const handleRoute = async (c: ListContext, noCache: boolean) => {
const type = c.req.query("type") || "1";
const { fromCache, data, updateTime } = await getList({ type }, noCache);
const routeData: RouterData = {
name: "sina-news",
title: "新浪新闻",
type: listType[type].name,
params: {
type: {
name: "榜单分类",
type: Object.fromEntries(Object.entries(listType).map(([key, value]) => [key, value.name])),
},
},
link: "https://sinanews.sina.cn/",
total: data?.length || 0,
updateTime,
fromCache,
data,
};
return routeData;
};
// JSONP 处理
const parseData = (data: string) => {
// 移除前后多余空白
if (!data) throw new Error("Input data is empty or invalid");
// 提取 JSON 字符串部分
const prefix = "var data = ";
if (!data.startsWith(prefix))
throw new Error("Input data does not start with the expected prefix");
let jsonString = data.slice(prefix.length).trim();
// 确保字符串以 ';' 结尾并移除它
if (jsonString.endsWith(";")) {
jsonString = jsonString.slice(0, -1).trim();
} else {
throw new Error("Input data does not end with a semicolon");
}
// 格式是否正确
if (jsonString.startsWith("{") && jsonString.endsWith("}")) {
// 解析为 JSON 对象
try {
const jsonData = JSON.parse(jsonString);
return jsonData;
} catch (error) {
throw new Error("Failed to parse JSON: " + error.message);
}
} else {
throw new Error("Invalid JSON format");
}
};
const getList = async (options: Options, noCache: boolean) => {
const { type } = options;
// 必要数据
const { params, www } = listType[type];
const { year, month, day } = getCurrentDateTime(true);
const url = `https://top.${www}.sina.com.cn/ws/GetTopDataList.php?top_type=day&top_cat=${params}&top_time=${year + month + day}&top_show_num=50`;
const result = await get({ url, noCache });
const list = parseData(result.data).data;
return {
fromCache: result.fromCache,
updateTime: result.updateTime,
data: list.map((v: RouterType["sina-news"]) => ({
id: v.id,
title: v.title,
author: v.media || null,
hot: parseFloat(v.top_num.replace(/,/g, "")),
timestamp: getTime(v.create_date + " " + v.create_time),
url: v.url,
mobileUrl: v.url,
})),
};
};

62
src/routes/sina.ts Normal file
View File

@@ -0,0 +1,62 @@
import type { RouterData, ListContext, Options } from "../types.js";
import type { RouterType } from "../router.types.js";
import { parseChineseNumber } from "../utils/getNum.js";
import { get } from "../utils/getData.js";
export const handleRoute = async (c: ListContext, noCache: boolean) => {
const type = c.req.query("type") || "1";
const { fromCache, data, updateTime } = await getList({ type }, noCache);
const routeData: RouterData = {
name: "sina",
title: "新浪网",
type: "热榜太多,一个就够",
params: {
type: {
name: "榜单分类",
type: {
all: "新浪热榜",
hotcmnt: "热议榜",
minivideo: "视频热榜",
ent: "娱乐热榜",
ai: "AI热榜",
auto: "汽车热榜",
mother: "育儿热榜",
fashion: "时尚热榜",
travel: "旅游热榜",
esg: "ESG热榜",
},
},
},
link: "https://sinanews.sina.cn/",
total: data?.length || 0,
updateTime,
fromCache,
data,
};
return routeData;
};
const getList = async (options: Options, noCache: boolean) => {
const { type } = options;
const url = `https://newsapp.sina.cn/api/hotlist?newsId=HB-1-snhs%2Ftop_news_list-${type}`;
const result = await get({ url, noCache });
const list = result.data.data.hotList;
return {
fromCache: result.fromCache,
updateTime: result.updateTime,
data: list.map((v: RouterType["sina"]) => {
const base = v.base;
const info = v.info;
return {
id: base.base.uniqueId,
title: info.title,
desc: null,
author: null,
timestamp: null,
hot: parseChineseNumber(info.hotValue),
url: base.base.url,
mobileUrl: base.base.url,
};
}),
};
};

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "sspai",
title: "少数派",
type: "热榜",
parame: {
params: {
type: {
name: "分类",
type: ["热门文章", "应用推荐", "生活方式", "效率技巧", "少数派播客"],

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "starrail",
title: "崩坏:星穹铁道",
type: "最新动态",
parame: {
params: {
type: {
name: "榜单分类",
type: {

View File

@@ -9,7 +9,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "v2ex",
title: "V2EX",
type: "主题榜",
parame: {
params: {
type: {
name: "榜单分类",
type: {

View File

@@ -10,7 +10,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => {
name: "weatheralarm",
title: "中央气象台",
type: type || "全国气象预警",
parame: {
params: {
province: {
name: "预警区域",
value: "省份名称( 例如:广东省 ",