diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 4e8a6ca9d4..71386b2606 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -2447,6 +2447,15 @@ }, ], }, + 'craigslist.org': { + _name: 'Craigslist', + '.': [ + { + title: '商品搜索列表', + docs: 'https://docs.rsshub.app/shopping.html#craigslist', + }, + ], + }, 'saraba1st.com': { _name: 'Saraba1st', bbs: [ diff --git a/docs/shopping.md b/docs/shopping.md index 245fb3049d..eae0a16575 100644 --- a/docs/shopping.md +++ b/docs/shopping.md @@ -36,6 +36,19 @@ pageClass: routes +## Craigslist + +### 商品搜索 + + + +> 由于 Craigslist 取消了 RSS 订阅搜索功能,因此用 RSSHub 来实现了类似效果。 +> 一个完整原始搜索会像这样: +> +> +> /search/xxx 后跟的 "xxx" 为搜索类型,直接参考原始请求即可。 +> query string 是实际的搜索内容。 + ## Furstar ### 最新售卖角色列表 diff --git a/lib/router.js b/lib/router.js index f3bfeb4c87..7926d84115 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3704,4 +3704,7 @@ router.get('/asml/press-releases', require('./routes/asml/press-releases')); // 中国机械工程学会 router.get('/cmes/news/:category?', require('./routes/cmes/news')); +// Craigslist +router.get('/craigslist/:location/:type', require('./routes/craigslist/search')); + module.exports = router; diff --git a/lib/routes/craigslist/search.js b/lib/routes/craigslist/search.js new file mode 100644 index 0000000000..691f79f040 --- /dev/null +++ b/lib/routes/craigslist/search.js @@ -0,0 +1,46 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const queryParams = ctx.request.querystring; + const queryUrl = `https://${ctx.params.location}.craigslist.org/search/${ctx.params.type}?${queryParams}`; + const { data } = await got.get(queryUrl); + const $ = cheerio.load(data); + const items = $('.result-row') + .slice(0, 20) + .map((_, _item) => { + const item = $(_item); + const info = item.find('.result-info').first(); + const titleNode = info.find('.result-title').first(); + const price = info.find('.result-price').first().text(); + const hood = info.find('.result-hood').first().text(); + const date = info.find('time').first().attr('datetime'); + + const dataIds = item.find('.result-image').first().attr('data-ids'); + let desc = ''; + if (dataIds) { + const imageList = dataIds.split(',').map((id) => ``); + desc = imageList.join(''); + } + return { + title: price + ' - ' + titleNode.text() + hood, + link: titleNode.attr('href'), + description: desc, + pubDate: date, + guid: titleNode.attr('id'), + }; + }) + .get(); + const urlParams = new URLSearchParams(queryParams); + let itemName = urlParams.get('query'); + if (!itemName) { + itemName = ''; + } else { + itemName = itemName.replace('+', ' '); + } + ctx.state.data = { + title: itemName + ' - Craigslist', + link: queryUrl, + item: items, + }; +};