Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(route): add 秀动网 (#12489) #13866

Merged
merged 14 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/v2/showstart/event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { fetchShowRSS } = require('./service');

module.exports = async (ctx) => {
const { data, $ } = await fetchShowRSS({
cityCode: ctx.params.cityCode,
showStyle: ctx.params.showStyle,
});

const tags = $('.tools-bar .tag')
.toArray()
.map((item) => $(item).text())
.join(' - ');

ctx.state.data = {
...data,
title: `${data.title} - ${tags}`,
};
};
4 changes: 4 additions & 0 deletions lib/v2/showstart/maintainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'/event/:cityCode/:showStyle?': ['lchtao26'],
'/search/:keyword': ['lchtao26'],
};
28 changes: 28 additions & 0 deletions lib/v2/showstart/radar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
'showstart.com': {
_name: '秀动网',
www: [
{
title: '演出更新',
docs: 'https://docs.rsshub.app/routes/shopping#xiu-dong-wang-yan-chu-geng-xin',
source: ['/event/list'],
target: (_, url) => {
lchtao26 marked this conversation as resolved.
Show resolved Hide resolved
const search = new URL(url).searchParams;
const cityCode = search.get('cityCode') || 0;
const showStyle = search.get('showStyle') || 0;
return `/showstart/event/${cityCode}/${showStyle}`;
},
},
{
title: '演出搜索',
docs: 'https://docs.rsshub.app/routes/shopping#xiu-dong-wang-yan-chu-sou-suo',
source: ['/event/list'],
target: (_, url) => {
lchtao26 marked this conversation as resolved.
Show resolved Hide resolved
const search = new URL(url).searchParams;
const keyword = search.get('keyword') || '';
return `/showstart/search/${keyword}`;
},
},
],
},
};
4 changes: 4 additions & 0 deletions lib/v2/showstart/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = (router) => {
router.get('/event/:cityCode/:showStyle?', require('./event'));
router.get('/search/:keyword', require('./search'));
};
12 changes: 12 additions & 0 deletions lib/v2/showstart/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { fetchShowRSS } = require('./service');

module.exports = async (ctx) => {
const keyword = ctx.params.keyword;
const { data } = await fetchShowRSS({
keyword,
});
ctx.state.data = {
...data,
title: `${data.title} - ${keyword}`,
};
};
44 changes: 44 additions & 0 deletions lib/v2/showstart/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const qs = require('query-string');
const got = require('@/utils/got');
const cheerio = require('cheerio');

const host = 'https://www.showstart.com';

async function fetchShowRSS({ keyword, showStyle, cityCode }) {
const url = `${host}/event/list?${qs.stringify(
{
pageNo: 1,
pageSize: 30,
cityCode: cityCode || '',
showStyle: showStyle || '',
keyword: keyword || '',
},
{
skipEmptyString: true,
}
)}`;

const respond = await got.get(url);
const $ = cheerio.load(respond.data);

const items = $('.list-box .show-item')
.toArray()
.map((item) => ({
title: $(item).find('.title').text(),
link: host + $(item).attr('href'),
description: $(item).find('.addr').text(),
}));

return {
$,
data: {
title: '秀动网',
link: host,
item: items,
},
};
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use their web API at /api/web/activity/list instead.

Quick Snippets
event.js
const { post, getAccessToken } = require('./utils');

module.exports = async (ctx) => {
    const accessToken = await getAccessToken();

    const result = await post('/web/activity/list', accessToken, {
        pageNo: '1',
        pageSize: '20',
        cityCode: '', // ctx.params.cityCode
        activityIds: '',
        coupon: '',
        keyword: '',
        organizerId: '',
        performerId: '',
        showStyle: '',
        showTime: '',
        showType: '',
        siteId: '',
        sortType: '',
        themeId: '',
        timeRange: '',
        tourId: '',
        type: '',
        tag: '',
    });

    console.log(JSON.stringify(result));
};
utils.js
const got = require('@/utils/got');
const md5 = require('@/utils/md5');

const uuid = (length = 20) => {
    const e = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + Date.now();
    const r = [];
    for (let i = 0; i < length; i++) {
        r.push(e.charAt(Math.floor(Math.random() * e.length)));
    }
    return r.join('');
};

const cookieMap = new Map([['token', uuid(32).toLowerCase()]]);

const devioceInfo = {
    vendorName: '',
    deviceMode: '',
    deviceName: '',
    systemName: '',
    systemVersion: '',
    cpuMode: ' ', // Note the space
    cpuCores: '',
    cpuArch: '',
    memerySize: '',
    diskSize: '',
    network: '',
    resolution: '1920*1080',
    pixelResolution: '',
};

const getAccessToken = async () => {
    const { result } = await post('/waf/gettoken');
    cookieMap.set('accessToken', result.accessToken.access_token);
    cookieMap.set('idToken', result.idToken.id_token);
    return cookieMap.get('accessToken');
};

const post = async (requestPath, accessToken = md5(Date.now().toString()), payload) => {
    const traceId = uuid(32) + Date.now();

    const { data: response } = await got.post(`https://www.showstart.com/api${requestPath}`, {
        headers: {
            cdeviceinfo: encodeURIComponent(JSON.stringify(devioceInfo)),
            cdeviceno: cookieMap.get('token'),
            cookie: [...cookieMap.entries()].map(([key, value]) => `${key}=${value}`).join('; '),
            crpsign: md5(accessToken + 'web' + cookieMap.get('token') + (payload ? JSON.stringify(payload) : '') + requestPath + '999web' + traceId),
            crtraceid: traceId,
            csappid: 'web',
            cterminal: 'web',
            cusat: accessToken,
            cusid: '',
            cusit: '',
            cusname: '',
            cusut: '',
            cversion: '999',
        },
        json: payload,
    });

    return response;
};

module.exports = {
    post,
    getAccessToken,
    uuid,
};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also obtain a mapping of cityCode, showStyle using

await post('/web/activity/list/params', accessToken)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, It's really helpful, I will change the code later.


module.exports = {
fetchShowRSS,
};
12 changes: 12 additions & 0 deletions website/docs/routes/shopping.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,18 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3

城市、分类名、子分类名,请参见[大麦网搜索页面](https://search.damai.cn/search.htm)

## 秀动网 {#xiu-dong-wang}

### 演出更新 {#xiu-dong-wang-yan-chu-geng-xin}

<Route author="lchtao26" example="/showstart/event/571/3" path="/showstart/event/:cityCode/:showStyle?" paramsDesc={['演出城市 (编号)', '演出风格 (编号)']}/>

相关路由参数可在 URL 中找到,如:`https://www.showstart.com/event/list?pageNo=1&pageSize=20&cityCode=571&showStyle=26`

### 演出搜索 {#xiu-dong-wang-yan-chu-sou-suo}

<Route author="lchtao26" example="/showstart/search/live" path="/showstart/search/:keyword" paramsDesc={['搜索关键词']}/>

## 多抓鱼 {#duo-zhua-yu}

### 搜索结果 {#duo-zhua-yu-sou-suo-jie-guo}
Expand Down