forked from imsyy/DailyHotApi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support Github trending, hackernews and producthunt
Now support source from Github Trending, hackernews and producthunt
- Loading branch information
Showing
4 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import type { RouterData } from "../types.js"; | ||
import { get } from "../utils/getData.js"; | ||
import { load } from "cheerio"; | ||
import type { RouterType } from "../router.types.js"; | ||
|
||
export const handleRoute = async (_: undefined, noCache: boolean) => { | ||
const listData = await getList(noCache); | ||
const routeData: RouterData = { | ||
name: "github", | ||
title: "GitHub", | ||
type: "Trending", | ||
description: "See what the GitHub community is most excited about today", | ||
link: "https://github.com/trending", | ||
total: listData.data?.length || 0, | ||
...listData, | ||
}; | ||
return routeData; | ||
}; | ||
|
||
const getList = async (noCache: boolean) => { | ||
const baseUrl = "https://github.com"; | ||
const result = await get({ | ||
url: `${baseUrl}/trending?spoken_language_code=`, | ||
noCache, | ||
headers: { | ||
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" | ||
} | ||
}); | ||
|
||
try { | ||
const $ = load(result.data); | ||
const stories: RouterType["github"][] = []; | ||
|
||
$("main .Box div[data-hpc] > article").each((_, el) => { | ||
const a = $(el).find(">h2 a"); | ||
const title = a.text().replace(/\n+/g, "").trim(); | ||
const path = a.attr("href"); | ||
const star = $(el).find("[href$=stargazers]").text().replace(/\s+/g, "").trim(); | ||
const desc = $(el).find(">p").text().replace(/\n+/g, "").trim(); | ||
|
||
if (path && title) { | ||
stories.push({ | ||
id: path.slice(1), // 移除开头的 / | ||
title, | ||
desc, | ||
hot: parseInt(star.replace(/,/g, "")) || undefined, | ||
timestamp: undefined, | ||
url: `${baseUrl}${path}`, | ||
mobileUrl: `${baseUrl}${path}`, | ||
}); | ||
} | ||
}); | ||
|
||
return { | ||
...result, | ||
data: stories, | ||
}; | ||
} catch (error) { | ||
throw new Error(`Failed to parse GitHub Trending HTML: ${error}`); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import type { RouterData } from "../types.js"; | ||
import { get } from "../utils/getData.js"; | ||
import { load } from "cheerio"; | ||
import type { RouterType } from "../router.types.js"; | ||
|
||
export const handleRoute = async (_: undefined, noCache: boolean) => { | ||
const listData = await getList(noCache); | ||
const routeData: RouterData = { | ||
name: "hackernews", | ||
title: "Hacker News", | ||
type: "Popular", | ||
description: "News about hacking and startups", | ||
link: "https://news.ycombinator.com/", | ||
total: listData.data?.length || 0, | ||
...listData, | ||
}; | ||
return routeData; | ||
}; | ||
|
||
const getList = async (noCache: boolean) => { | ||
const baseUrl = "https://news.ycombinator.com"; | ||
const result = await get({ | ||
url: baseUrl, | ||
noCache, | ||
headers: { | ||
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" | ||
} | ||
}); | ||
|
||
try { | ||
const $ = load(result.data); | ||
const stories: RouterType["hackernews"][] = []; | ||
|
||
$(".athing").each((_, el) => { | ||
const item = $(el); | ||
const id = item.attr("id") || ""; | ||
const title = item.find(".titleline a").first().text().trim(); | ||
const url = item.find(".titleline a").first().attr("href"); | ||
|
||
// 获取分数并转换为数字 | ||
const scoreText = $(`#score_${id}`).text().match(/\d+/)?.[0]; | ||
const hot = scoreText ? parseInt(scoreText, 10) : undefined; | ||
|
||
if (id && title) { | ||
stories.push({ | ||
id, | ||
title, | ||
hot, | ||
timestamp: undefined, | ||
url: url || `${baseUrl}/item?id=${id}`, | ||
mobileUrl: url || `${baseUrl}/item?id=${id}`, | ||
}); | ||
} | ||
}); | ||
|
||
return { | ||
...result, | ||
data: stories, | ||
}; | ||
} catch (error) { | ||
throw new Error(`Failed to parse HackerNews HTML: ${error}`); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import type { RouterData } from "../types.js"; | ||
import { get } from "../utils/getData.js"; | ||
import { load } from "cheerio"; | ||
import type { RouterType } from "../router.types.js"; | ||
|
||
export const handleRoute = async (_: undefined, noCache: boolean) => { | ||
const listData = await getList(noCache); | ||
const routeData: RouterData = { | ||
name: "producthunt", | ||
title: "Product Hunt", | ||
type: "Today", | ||
description: "The best new products, every day", | ||
link: "https://www.producthunt.com/", | ||
total: listData.data?.length || 0, | ||
...listData, | ||
}; | ||
return routeData; | ||
}; | ||
|
||
const getList = async (noCache: boolean) => { | ||
const baseUrl = "https://www.producthunt.com"; | ||
const result = await get({ | ||
url: baseUrl, | ||
noCache, | ||
headers: { | ||
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" | ||
} | ||
}); | ||
|
||
try { | ||
const $ = load(result.data); | ||
const stories: RouterType["producthunt"][] = []; | ||
|
||
$("[data-test=homepage-section-0] [data-test^=post-item]").each((_, el) => { | ||
const a = $(el).find("a").first(); | ||
const path = a.attr("href"); | ||
const title = $(el).find("a[data-test^=post-name]").text().trim(); | ||
const id = $(el).attr("data-test")?.replace("post-item-", ""); | ||
const vote = $(el).find("[data-test=vote-button]").text().trim(); | ||
|
||
if (path && id && title) { | ||
stories.push({ | ||
id, | ||
title, | ||
hot: parseInt(vote) || undefined, | ||
timestamp: undefined, | ||
url: `${baseUrl}${path}`, | ||
mobileUrl: `${baseUrl}${path}`, | ||
}); | ||
} | ||
}); | ||
|
||
return { | ||
...result, | ||
data: stories, | ||
}; | ||
} catch (error) { | ||
throw new Error(`Failed to parse Product Hunt HTML: ${error}`); | ||
} | ||
}; |