diff --git a/docs/en/new-media.md b/docs/en/new-media.md
index 73dcb4548..e2b4dea48 100644
--- a/docs/en/new-media.md
+++ b/docs/en/new-media.md
@@ -581,12 +581,6 @@ Compared to the official one, this feed:
-## Research Gate
-
-### Publications
-
-
-
## RSS3
### Blog
diff --git a/docs/en/study.md b/docs/en/study.md
index 589148f79..2e5367d93 100644
--- a/docs/en/study.md
+++ b/docs/en/study.md
@@ -108,6 +108,12 @@ pageClass: routes
+## ResearchGate
+
+### Publications
+
+
+
## X-MOL
### News
diff --git a/docs/new-media.md b/docs/new-media.md
index 9acdc7d1a..4b85817d8 100644
--- a/docs/new-media.md
+++ b/docs/new-media.md
@@ -1187,12 +1187,6 @@ IPFS 网关有可能失效,那时候换成其他网关。
-## Research Gate
-
-### Publications
-
-
-
## RSS3
### Blog
diff --git a/docs/study.md b/docs/study.md
index ae233e10a..db8106c84 100644
--- a/docs/study.md
+++ b/docs/study.md
@@ -234,6 +234,12 @@ path="/ctfhub/upcoming/:limit?"
+## ResearchGate
+
+### Publications
+
+
+
## X-MOL 平台
### 新闻
diff --git a/lib/router.js b/lib/router.js
index 1a6dfbbdc..8e7bd61cd 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -4028,7 +4028,7 @@ router.get('/sbs/chinese/:category?/:id?/:dialect?/:language?', lazyloadRouteHan
// router.get('/asiantolick/:category?/:keyword?', lazyloadRouteHandler('./routes/asiantolick'));
// Research Gate
-router.get('/researchgate/publications/:id', lazyloadRouteHandler('./routes/researchgate/publications'));
+// router.get('/researchgate/publications/:id', lazyloadRouteHandler('./routes/researchgate/publications'));
// QuestMobile
router.get('/questmobile/report/:category?/:label?', lazyloadRouteHandler('./routes/questmobile/report'));
diff --git a/lib/routes/researchgate/publications.js b/lib/routes/researchgate/publications.js
deleted file mode 100644
index 6d469ea92..000000000
--- a/lib/routes/researchgate/publications.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const rootUrl = 'https://www.researchgate.net';
- const currentUrl = `${rootUrl}/profile/${id}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('div[itemprop="headline"] a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map(
- async (item) =>
- await ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.doi = content('meta[property="citation_doi"]').attr('content');
- item.pubDate = Date.parse(content('meta[property="citation_publication_date"]').attr('content'));
-
- const authors = [];
-
- content('meta[property="citation_author"]').each(function () {
- authors.push(content(this).attr('content'));
- });
-
- item.author = authors.join(', ');
-
- item.description = content('div[itemprop="description"]').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('meta[property="profile:username"]').attr('content')}'s Publications - ResearchGate`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/v2/researchgate/maintainer.js b/lib/v2/researchgate/maintainer.js
new file mode 100644
index 000000000..1422d9e67
--- /dev/null
+++ b/lib/v2/researchgate/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/publications/:username': ['nczitzk'],
+};
diff --git a/lib/v2/researchgate/publications.js b/lib/v2/researchgate/publications.js
new file mode 100644
index 000000000..8451f6c67
--- /dev/null
+++ b/lib/v2/researchgate/publications.js
@@ -0,0 +1,70 @@
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+
+ const rootUrl = 'https://www.researchgate.net';
+ const currentUrl = `${rootUrl}/profile/${id}`;
+ const browser = await require('@/utils/puppeteer')();
+ const page = await browser.newPage();
+ await page.setRequestInterception(true);
+ page.on('request', (request) => {
+ request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
+ });
+ await page.goto(currentUrl);
+ const response = await page.evaluate(() => document.documentElement.innerHTML);
+ await page.close();
+
+ const $ = cheerio.load(response);
+
+ const list = $('div[itemprop="headline"] a')
+ .toArray()
+ .slice(0, ctx.query.limit ? Number(ctx.query.limit) : 15)
+ .map((item) => {
+ item = $(item);
+ return {
+ title: item.text(),
+ link: item.attr('href'),
+ };
+ });
+
+ const items = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const page = await browser.newPage();
+ await page.setRequestInterception(true);
+ page.on('request', (request) => {
+ request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
+ });
+ await page.goto(item.link);
+ const detailResponse = await page.evaluate(() => document.documentElement.innerHTML);
+ await page.close();
+ const content = cheerio.load(detailResponse);
+
+ item.doi = content('meta[property="citation_doi"]').attr('content');
+ item.pubDate = parseDate(content('meta[property="citation_publication_date"]').attr('content'));
+
+ const authors = [];
+
+ content('meta[property="citation_author"]').each(function () {
+ authors.push(content(this).attr('content'));
+ });
+
+ item.author = authors.join(', ');
+
+ item.description = content('div[itemprop="description"]').html();
+
+ return item;
+ })
+ )
+ );
+
+ await browser.close();
+
+ ctx.state.data = {
+ title: `${$('meta[property="profile:username"]').attr('content')}'s Publications - ResearchGate`,
+ link: currentUrl,
+ item: items,
+ };
+};
diff --git a/lib/v2/researchgate/radar.js b/lib/v2/researchgate/radar.js
new file mode 100644
index 000000000..4df44cdec
--- /dev/null
+++ b/lib/v2/researchgate/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'researchgate.net': {
+ _name: 'ResearchGate',
+ '.': [
+ {
+ title: 'Publications',
+ docs: 'https://docs.rsshub.app/study.html#researchgate',
+ source: ['/profile/:username'],
+ target: '/researchgate/publications/:username',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/researchgate/router.js b/lib/v2/researchgate/router.js
new file mode 100644
index 000000000..ae42543bf
--- /dev/null
+++ b/lib/v2/researchgate/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/publications/:id', require('./publications'));
+};