diff --git a/docs/traditional-media.md b/docs/traditional-media.md index 62aa535f47..80cb416c24 100644 --- a/docs/traditional-media.md +++ b/docs/traditional-media.md @@ -131,6 +131,28 @@ Solidot 提供的 feed: +## Telecompaper + +### News + + + +可选分类如下 + +| WIRELESS | BROADBAND | VIDEO | GENERAL | IT | INDUSTRY RESOURCES | +| -------- | --------- | --------- | ------- | -- | ------------------ | +| mobile | internet | boardcast | general | it | industry-resources | + +::: tip 提示 + +若 `country` 或 `type` 参数包含空格,则用 `-` 替代。如 `United States` 更换为 `United-States`,`White paper` 更换为 `White-paper` + +[INDUSTRY RESOURCES](https://www.telecompaper.com/industry-resources) 分类页的 Filter 仅提供了 `Content Type` 选择器,对应路由中 `type` 参数。`year` 和 `country` 参数则对该分类无效。 + +::: + + + ## The Economist ### 分类 diff --git a/lib/router.js b/lib/router.js index d7e19c942e..6210daf848 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3046,4 +3046,7 @@ router.get('/scvtc/xygg', require('./routes/universities/scvtc/xygg')); // OneJAV router.get('/onejav/:type/:key?', require('./routes/onejav/one')); +// Telecompaper +router.get('/telecompaper/news/:caty/:year?/:country?/:type?/:keyword?', require('./routes/telecompaper/news')); + module.exports = router; diff --git a/lib/routes/telecompaper/news.js b/lib/routes/telecompaper/news.js new file mode 100644 index 0000000000..5dfb9fd859 --- /dev/null +++ b/lib/routes/telecompaper/news.js @@ -0,0 +1,107 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const tough = require('tough-cookie'); +const FormData = require('form-data'); + +module.exports = async (ctx) => { + const rootUrl = `https://www.telecompaper.com/${ctx.params.caty === 'industry-resources' ? ctx.params.caty : 'international/news/' + ctx.params.caty}`; + const year = ctx.params.year ? ctx.params.year : 'all'; + const country = ctx.params.country ? ctx.params.country.split('-').join(' ') : 'all'; + const type = ctx.params.type ? ctx.params.type.split('-').join(' ') : 'all'; + + const cookieJar = new tough.CookieJar(); + let response = await got({ + method: 'get', + url: rootUrl, + cookieJar, + }), + $ = cheerio.load(response.data); + + const form = new FormData(); + form.append('__EVENTTARGET', 'ctl00$MainPlaceHolder$ddlContentType'); + form.append('__EVENTARGUMENT', ''); + form.append('__LASTFOCUS', ''); + form.append('__VIEWSTATE', $('#__VIEWSTATE').attr('value')); + form.append('__VIEWSTATEGENERATOR', 'E4EF4CD1'); + form.append('ctl00$header$searchText', ctx.params.keyword || ''); + form.append('ctl00$header$searchTextMobile', ctx.params.keyword || ''); + if (ctx.params.caty !== 'industry-resources') { + form.append( + 'ctl00$MainPlaceHolder$ddlYears', + year && year !== 'all' + ? $('select[name="ctl00$MainPlaceHolder$ddlYears"] option') + .filter(function (index, element) { + return $(element).text().split(' (')[0] === ctx.params.year; + }) + .attr('value') + : '0' + ); + form.append( + 'ctl00$MainPlaceHolder$ddlCountries', + country && country !== 'all' + ? $('select[name="ctl00$MainPlaceHolder$ddlCountries"] option') + .filter(function (index, element) { + return $(element).text().split(' (')[0] === country; + }) + .attr('value') + : '0' + ); + } + form.append( + 'ctl00$MainPlaceHolder$ddlContentType', + type && type !== 'all' + ? $('select[name="ctl00$MainPlaceHolder$ddlContentType"] option') + .filter(function (index, element) { + return $(element).text().split(' (')[0] === type; + }) + .attr('value') + : '' + ); + + response = await got({ + method: 'post', + url: rootUrl, + cookieJar, + header: { + referer: 'https://www.telecompaper.com/international/news/mobile', + }, + body: form, + }); + $ = cheerio.load(response.data); + + const list = $('table.details_rows tbody tr') + .slice(0, 10) + .map((_, item) => { + item = $(item); + const a = item.find('a'); + return { + title: a.text(), + link: a.attr('href'), + pubDate: new Date(item.find('span.source').text().replace('Published ', '').split(' CET | ')[0] + ' GMT+1').toUTCString(), + }; + }) + .get(); + + const items = await Promise.all( + list.map( + async (item) => + await ctx.cache.tryGet(item.link, async () => { + const detailResponse = await got({ + method: 'get', + url: item.link, + }); + const content = cheerio.load(detailResponse.data); + + item.description = content('#pageContainer').html(); + + return item; + }) + ) + ); + + ctx.state.data = { + title: 'Telecompaper - ' + $('h1').text(), + link: rootUrl, + item: items, + }; +};