feat(route): add 中华人民共和国国家应急管理部信息公开 (#19934)

* ## Involved Issue / 该 PR 相关 Issue

Close #

## Example for the Proposed Route(s) / 路由地址示例

```routes
/gov/mem/gk/zfxxgkpt/fdzdgknr
```

## New RSS Route Checklist / 新 RSS 路由检查表

- [x] New Route / 新的路由
- [x] Follows [Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard)
- [ ] Documentation / 文档说明
- [ ] Full text / 全文获取
- [x] Use cache / 使用缓存
- [ ] Anti-bot or rate limit / 反爬/频率限制
- [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施?
- [x] [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) / [日期和时间](https://docs.rsshub.app/zh/joinus/advanced/pub-date)
- [x] Parsed / 可以解析
- [x] Correct time zone / 时区正确
- [ ] New package added / 添加了新的包
- [ ] `Puppeteer`

## Note / 说明

* ## Involved Issue / 该 PR 相关 Issue

Close #

## Example for the Proposed Route(s) / 路由地址示例

```routes
/gov/mem/gk/zfxxgkpt/fdzdgknr
```

## New RSS Route Checklist / 新 RSS 路由检查表

- [x] New Route / 新的路由
- [x] Follows [Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard)
- [ ] Documentation / 文档说明
- [ ] Full text / 全文获取
- [x] Use cache / 使用缓存
- [ ] Anti-bot or rate limit / 反爬/频率限制
- [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施?
- [x] [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) / [日期和时间](https://docs.rsshub.app/zh/joinus/advanced/pub-date)
- [x] Parsed / 可以解析
- [x] Correct time zone / 时区正确
- [ ] New package added / 添加了新的包
- [ ] `Puppeteer`

## Note / 说明

* ## Involved Issue / 该 PR 相关 Issue

Close #

## Example for the Proposed Route(s) / 路由地址示例

```routes
/gov/mem/gk/zfxxgkpt/fdzdgknr
```

## New RSS Route Checklist / 新 RSS 路由检查表

- [x] New Route / 新的路由
- [x] Follows [Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard)
- [ ] Documentation / 文档说明
- [ ] Full text / 全文获取
- [x] Use cache / 使用缓存
- [ ] Anti-bot or rate limit / 反爬/频率限制
- [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施?
- [x] [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) / [日期和时间](https://docs.rsshub.app/zh/joinus/advanced/pub-date)
- [x] Parsed / 可以解析
- [x] Correct time zone / 时区正确
- [ ] New package added / 添加了新的包
- [ ] `Puppeteer`

## Note / 说明

* feat(route): add 中华人民共和国国家应急管理部信息公开

* refactor(route): 重构数据提取部分

- Use the redirected URL instead
- update description
- not select table heading in the selector
- delete try catch block(verified that try-catch is not needed.)

* fix: add namespace

* fix: remove unnecessary template literal

---------
This commit is contained in:
skeaven chen 2025-08-30 22:08:50 +08:00 committed by GitHub
parent c68acb318e
commit a8e3fee462
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,7 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: '中华人民共和国应急管理部',
url: 'www.mem.gov.cn',
lang: 'zh-CN',
};

View File

@ -0,0 +1,96 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/mem/gk/zfxxgkpt/fdzdgknr',
categories: ['government'],
example: '/gov/mem/gk/zfxxgkpt/fdzdgknr',
parameters: {},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['www.mem.gov.cn/gk/zfxxgkpt/fdzdgknr'],
target: '/mem/gk/zfxxgkpt/fdzdgknr',
},
],
name: '法定主动公开内容',
maintainers: ['skeaven'],
handler,
description: '应急管理部法定主动公开内容,包含通知、公告、督办、政策解读等,可供应急相关工作人员及时获取政策信息',
};
async function handler(ctx) {
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30;
const rootUrl = 'https://www.mem.gov.cn';
const currentUrl = new URL('gk/zfxxgkpt/fdzdgknr/', rootUrl).href;
const { data: fdzdgknrResponse } = await got(currentUrl);
const fdzdgknr$ = load(fdzdgknrResponse);
const iframeUrl = fdzdgknr$('div.scy_main_r iframe').attr('src');
const { data: response } = await got(iframeUrl);
const $ = load(response);
const icon = new URL('favicon.ico', rootUrl).href;
let items = $('div.scy_main_V2_list')
.find('tr')
.slice(1, limit)
.toArray()
.map((item) => {
const aLabel = $(item).find('a[href]');
const href = aLabel.attr('href');
if (href) {
const link = currentUrl + aLabel.attr('href').replaceAll('..', '');
return {
title: aLabel.contents().first().text(),
link,
pubDate: parseDate($(item).find('.fbsj').text()),
};
} else {
return null;
}
})
.filter(Boolean);
items = await Promise.all(
items.map((item) =>
cache.tryGet(item.link, async () => {
if (!item.link.endsWith('.html') && !item.link.endsWith('.shtml')) {
return item;
}
const { data: detailResponse } = await got(item.link);
const content = load(detailResponse);
const description = content('#content').html();
const author = content('td.td_lable:contains("所属机构")').next('td').text().trim();
const category = content('td.td_lable:contains("主题分类")').next('td').text().trim();
return {
...item,
description,
author: author || '未知机构',
category: category || '未知分类',
};
})
)
);
return {
item: items,
title: route.name,
link: currentUrl,
icon,
};
}