diff --git a/docs/en/program-update.md b/docs/en/program-update.md
index e206db395..a85083b25 100644
--- a/docs/en/program-update.md
+++ b/docs/en/program-update.md
@@ -22,11 +22,11 @@ pageClass: routes
-## Apkpure
+## APKPure
### Versions
-
+
## App Center
@@ -116,7 +116,7 @@ Language
### BlueStacks 5 Release Notes
-
+
## Brave
diff --git a/docs/program-update.md b/docs/program-update.md
index 66ed5c4fd..8074916f3 100644
--- a/docs/program-update.md
+++ b/docs/program-update.md
@@ -32,11 +32,11 @@ pageClass: routes
-## Apkpure
+## APKPure
-### Versions
+### 所有版本
-
+
## App Center
@@ -114,7 +114,7 @@ pageClass: routes
### BlueStacks 5 版本日誌
-
+
## Brave
diff --git a/lib/router.js b/lib/router.js
index f99202a55..9b1d94e06 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -1088,7 +1088,7 @@ router.get('/anigamer/new_anime', lazyloadRouteHandler('./routes/anigamer/new_an
router.get('/anigamer/anime/:sn', lazyloadRouteHandler('./routes/anigamer/anime'));
// Apkpure
-router.get('/apkpure/versions/:region/:pkg', lazyloadRouteHandler('./routes/apkpure/versions'));
+// router.get('/apkpure/versions/:region/:pkg', lazyloadRouteHandler('./routes/apkpure/versions'));
// 豆瓣美女 migrated to v2
// router.get('/dbmv/:category?', lazyloadRouteHandler('./routes/dbmv/index'));
diff --git a/lib/routes/apkpure/versions.js b/lib/routes/apkpure/versions.js
deleted file mode 100644
index f108a85c6..000000000
--- a/lib/routes/apkpure/versions.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const { region, pkg } = ctx.params;
- const link = `https://apkpure.com/${region}/${pkg}/versions`;
- const $ = await got.get(link).then((r) => cheerio.load(r.data));
- const img = new URL($('.ver-top img').attr('src'));
- img.searchParams.delete('w'); // get full resolution icon
- ctx.state.data = {
- title: $('.ver-top-h1').text(),
- description: `
` + $('.ver-top-title>h2').text(),
- link: decodeURI(link),
- item: $('.ver li')
- .toArray()
- .map((ver) => ({
- title: $(ver).find('.ver-item-n').text(),
- description: $(ver).find('a').attr('title'),
- link: `https://apkpure.com${decodeURI($(ver).find('a').attr('href').split('?from')[0])}`,
- pubDate: new Date($(ver).find('.update-on').text().replace(/年|月/g, '-').replace('日', '')).toUTCString(),
- })),
- };
-};
diff --git a/lib/v2/apkpure/maintainer.js b/lib/v2/apkpure/maintainer.js
new file mode 100644
index 000000000..b95ea3b28
--- /dev/null
+++ b/lib/v2/apkpure/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/versions/:pkg/:region?': ['maple3142'],
+};
diff --git a/lib/v2/apkpure/radar.js b/lib/v2/apkpure/radar.js
new file mode 100644
index 000000000..18ef4d5d6
--- /dev/null
+++ b/lib/v2/apkpure/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'apkpure.com': {
+ _name: 'APKPure',
+ '.': [
+ {
+ title: '所有版本',
+ docs: 'https://docs.rsshub.app/program-update.html#apkpure',
+ source: ['/:region/:stuff/:pkg/versions', '/:stuff/:pkg/versions', '/:stuff/:pkg'],
+ target: (params) => `/apkpure/versions/${params.pkg}${params.region ? `/${params.region}` : ''}`,
+ },
+ ],
+ },
+};
diff --git a/lib/v2/apkpure/router.js b/lib/v2/apkpure/router.js
new file mode 100644
index 000000000..6e779c25c
--- /dev/null
+++ b/lib/v2/apkpure/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/versions/:pkg/:region?', require('./versions'));
+};
diff --git a/lib/v2/apkpure/versions.js b/lib/v2/apkpure/versions.js
new file mode 100644
index 000000000..263b75d90
--- /dev/null
+++ b/lib/v2/apkpure/versions.js
@@ -0,0 +1,48 @@
+const cheerio = require('cheerio');
+const logger = require('@/utils/logger');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const { pkg, region = 'en' } = ctx.params;
+ const baseUrl = 'https://apkpure.com';
+ const link = `${baseUrl}/${region}/${pkg}/versions`;
+
+ const browser = await require('@/utils/puppeteer')();
+ const page = await browser.newPage();
+ await page.setRequestInterception(true);
+ page.on('request', (request) => {
+ request.resourceType() === 'document' ? request.continue() : request.abort();
+ });
+ logger.debug(`Requesting ${link}`);
+ await page.goto(link, {
+ waitUntil: 'domcontentloaded',
+ });
+
+ const r = await page.evaluate(() => document.documentElement.innerHTML);
+ browser.close();
+
+ const $ = cheerio.load(r);
+ const img = new URL($('.ver-top img').attr('src'));
+ img.searchParams.delete('w'); // get full resolution icon
+
+ const items = $('.ver li')
+ .toArray()
+ .map((ver) => {
+ ver = $(ver);
+ return {
+ title: ver.find('.ver-item-n').text(),
+ description: ver.html(),
+ link: `${baseUrl}${ver.find('a').attr('href')}`,
+ pubDate: parseDate(ver.find('.update-on').text().replace(/年|月/g, '-').replace('日', '')),
+ };
+ });
+
+ ctx.state.data = {
+ title: $('.ver-top-h1').text(),
+ description: $('.ver-top-title p').text(),
+ image: img.href,
+ language: region ? region : 'en',
+ link,
+ item: items,
+ };
+};