diff --git a/docs/program-update.md b/docs/program-update.md
index abd5b1920..cb37e8126 100644
--- a/docs/program-update.md
+++ b/docs/program-update.md
@@ -68,6 +68,16 @@ pageClass: routes
+## cpython
+
+### 正式版本发布
+
+
+
+### 所有版本发布
+
+
+
## CurseForge
### 文件更新
diff --git a/lib/router.js b/lib/router.js
index af80ebe87..57901c502 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -386,6 +386,9 @@ router.get('/tuicool/mags/:type', require('./routes/tuicool/mags'));
router.get('/hexo/next/:url', require('./routes/hexo/next'));
router.get('/hexo/yilia/:url', require('./routes/hexo/yilia'));
+// cpython
+router.get('/cpython/:pre?', require('./routes/cpython'));
+
// 小米
router.get('/mi/crowdfunding', require('./routes/mi/crowdfunding'));
router.get('/mi/youpin/crowdfunding', require('./routes/mi/youpin/crowdfunding'));
diff --git a/lib/routes/cpython/index.js b/lib/routes/cpython/index.js
new file mode 100644
index 000000000..7d9161ff0
--- /dev/null
+++ b/lib/routes/cpython/index.js
@@ -0,0 +1,32 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const dayjs = require('dayjs');
+
+module.exports = async (ctx) => {
+ const includePreRelease = ctx.params.pre;
+ const response = await got(`https://www.python.org/downloads`);
+ const $ = cheerio.load(response.data);
+ const items = [];
+ $('.list-row-container.menu li').each(function () {
+ const $listElement = $(this);
+ const title = $listElement.find('span.release-number').text();
+ if (title) {
+ if (!includePreRelease) {
+ if (title.includes('rc')) {
+ return;
+ }
+ }
+ items.push({
+ title: $listElement.find('span.release-number').text(),
+ description: title,
+ link: $listElement.find('.release-enhancements a').attr('href'),
+ pubDate: dayjs($listElement.find('.release-date').text()),
+ });
+ }
+ });
+ ctx.state.data = {
+ title: 'cpython',
+ link: 'https://www.python.org/',
+ item: items,
+ };
+};