feat: add mercari (#5748)

Co-authored-by: Henry Wang <hi@henry.wang>
This commit is contained in:
Ethan Shen 2020-10-03 06:44:01 +08:00 committed by GitHub
parent fa81ed9f0f
commit c2fd937417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 0 deletions

View File

@ -63,3 +63,15 @@ Transform any search into a feed.
For instance, in https://www.leboncoin.fr/recherche/?**category=10&locations=Paris_75015**, the query is **category=10&locations=Paris_75015**
</RouteEn>
## Mercari
### Goods
<RouteEn author="nczitzk" example="/mercari/category/1" path="/mercari/:type/:id" :paramsDesc="['`category` as seaching by category, `brand` as searching by brand, `search` as searching for keyword', 'can be found in URL of the category or brand page. If you choose `search` as `type`, then put keyword here']">
All categories, see [Category list](https://www.mercari.com/jp/category/)
All brands, see [Brand list](https://www.mercari.com/jp/brand/)
</RouteEn>

View File

@ -68,6 +68,18 @@ For instance, in <https://www.leboncoin.fr/recherche/?**category=10&locations=Pa
</Route>
## Mercari
### 商品
<Route author="nczitzk" example="/mercari/category/1" path="/mercari/:type/:id" :paramsDesc="['类型,可选 `category` 指按类别浏览,`brand` 指按品牌浏览,`search` 指搜索关键词浏览', 'id可在对应分类或品牌页 URL 中找到。若选择 `search` 作为 `type` 则此处填写关键词']">
所有分类参见 [分类清单](https://www.mercari.com/jp/category/)
所有品牌参见 [品牌清单](https://www.mercari.com/jp/brand/)
</Route>
## Westore
### 新品

View File

@ -3241,6 +3241,9 @@ router.get('/appsales/:caty?/:time?', require('./routes/appsales/index'));
// CGTN
router.get('/cgtn/top', require('./routes/cgtn/top'));
// Mercari
router.get('/mercari/:type/:id', require('./routes/mercari/index'));
// notefolio
router.get('/notefolio/:caty?/:order?/:time?/:query?', require('./routes/notefolio/index'));

View File

@ -0,0 +1,68 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
ctx.params.type = ctx.params.type === 'search' ? ctx.params.type + '/?keyword=' : ctx.params.type + '/';
const rootUrl = 'https://www.mercari.com';
const currentUrl = `${rootUrl}/jp/${ctx.params.type}${ctx.params.id}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
let list;
if (ctx.params.type === 'category/') {
list = JSON.parse(response.data.match(/"searchCategory":(.*?),"crossBorderBanner/)[1])
.data.slice(0, 10)
.map((item) => ({
title: item.name,
link: `${rootUrl}/jp/items/${item.id}/`,
}));
} else {
list = $('section.items-box')
.slice(0, 10)
.map((_, item) => {
item = $(item);
return {
title: item.find('h3.items-box-name').text(),
link: `${rootUrl}${item.find('a').attr('href')}`,
};
})
.get();
}
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
try {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('div.item-btn-float-area').remove();
content('div.owl-nav').remove();
content('div.owl-dots').remove();
item.description = content('div.item-main-content').html();
return item;
} catch (e) {
return Promise.resolve('');
}
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};