diff --git a/docs/en/shopping.md b/docs/en/shopping.md
index 511fcc301..099fc598f 100644
--- a/docs/en/shopping.md
+++ b/docs/en/shopping.md
@@ -36,6 +36,12 @@ Parameter `time` only works when `mostwanted` is chosen as the category.
+## booth.pm
+
+### Shop
+
+
+
## Guiltfree.pl
### Onsale
diff --git a/docs/shopping.md b/docs/shopping.md
index a058a5241..ad773c822 100644
--- a/docs/shopping.md
+++ b/docs/shopping.md
@@ -36,6 +36,12 @@ pageClass: routes
+## booth.pm
+
+### 店铺
+
+
+
## Craigslist
### 商品搜索
diff --git a/lib/router.js b/lib/router.js
index 46d98594b..ad181fc2e 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -3820,4 +3820,7 @@ router.get('/simpread/changelog', require('./routes/simpread/changelog'));
// Radio Free Asia
router.get('/rfa/:language?/:channel?/:subChannel?', require('./routes/rfa/index'));
+// booth.pm
+router.get('/booth.pm/shop/:subdomain', require('./routes/booth-pm/shop'));
+
module.exports = router;
diff --git a/lib/routes/booth-pm/shop.js b/lib/routes/booth-pm/shop.js
new file mode 100644
index 000000000..45bc0ad00
--- /dev/null
+++ b/lib/routes/booth-pm/shop.js
@@ -0,0 +1,57 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+const maxPages = 5;
+
+module.exports = async (ctx) => {
+ const { subdomain } = ctx.params;
+ const shopUrl = `https://${subdomain}.booth.pm`;
+
+ let shopName;
+ const items = [];
+ for (let page = 1; page <= maxPages; page++) {
+ const pageUrl = `${shopUrl}/items?page=${page}`;
+ // eslint-disable-next-line no-await-in-loop
+ const response = await got({
+ method: 'get',
+ url: pageUrl,
+ });
+
+ const data = response.data;
+
+ const $ = cheerio.load(data);
+ shopName = $('div.shop-name > span').text();
+ const pageItems = $('li.item');
+
+ if (pageItems.length === 0) {
+ break;
+ }
+
+ for (let i = 0; i < pageItems.length; ++i) {
+ const pageItem = pageItems[i];
+
+ // extract item name
+ const itemName = $('h2.item-name > a', pageItem).text();
+
+ // extract item url
+ const itemUrl = shopUrl + $('h2.item-name > a', pageItem).attr('href');
+
+ // extract item preview url
+ const itemPreviewUrl = $('div.swap-image > img', pageItem).attr('src');
+
+ items.push({
+ title: itemName,
+ description: `
`,
+ link: itemUrl,
+ });
+ }
+ }
+
+ ctx.state.data = {
+ title: shopName,
+ link: shopUrl,
+ description: shopName,
+ allowEmpty: true,
+ item: items,
+ };
+};