diff --git a/lib/v2/segmentfault/blogs.js b/lib/v2/segmentfault/blogs.js index 436d040c5..0ab77575c 100644 --- a/lib/v2/segmentfault/blogs.js +++ b/lib/v2/segmentfault/blogs.js @@ -1,34 +1,17 @@ const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); - -const host = 'https://segmentfault.com'; +const { host, acw_sc__v2, parseList, parseItems } = require('./utils'); module.exports = async (ctx) => { - const tag = ctx.params.tag; - const apiURL = `https://segmentfault.com/gateway/tag/${tag}/articles?loadMoreType=pagination&initData=true&page=1&sort=newest&pageSize=30`; + const { tag } = ctx.params; + const apiURL = `${host}/gateway/tag/${tag}/articles?loadMoreType=pagination&initData=true&page=1&sort=newest&pageSize=30`; const response = await got(apiURL); const data = response.data.rows; - const list = data.map((item) => ({ - title: item.title, - link: new URL(item.url, host).href, - author: item.user.name, - })); + const list = parseList(data); - const items = await Promise.all( - list.map((item) => - ctx.cache.tryGet(item.link, async () => { - const response = await got(item.link); - const content = cheerio.load(response.data); + const acwScV2Cookie = await acw_sc__v2(list[0].link, ctx.cache.tryGet); - item.description = content('article').html(); - item.pubDate = parseDate(content('time').attr('datetime')); - - return item; - }) - ) - ); + const items = await Promise.all(list.map((item) => parseItems(acwScV2Cookie, item, ctx.cache.tryGet))); ctx.state.data = { title: `segmentfault-Blogs-${tag}`, diff --git a/lib/v2/segmentfault/channel.js b/lib/v2/segmentfault/channel.js index 536015904..244e5be20 100644 --- a/lib/v2/segmentfault/channel.js +++ b/lib/v2/segmentfault/channel.js @@ -1,45 +1,33 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); - -const host = 'https://segmentfault.com'; +const { host, acw_sc__v2, parseList, parseItems } = require('./utils'); module.exports = async (ctx) => { - const name = ctx.params.name; + const { name } = ctx.params; const link = `${host}/channel/${name}`; - const response = await got(link); - const $ = cheerio.load(response.data); + const { data: pageResponse } = await got(link); + const { data: apiResponse } = await got(`${host}/gateway/articles`, { + searchParams: { + query: 'channel', + slug: name, + offset: 0, + size: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 20, + mode: 'scrollLoad', + }, + }); - const channel_name = $('#leftNav > a.active').text(); + const $ = cheerio.load(pageResponse); + const channelName = $('#leftNav > a.active').text(); - const list = $('ul.bg-transparent.list-group.list-group-flush > li') - .slice(0, 10) - .map((_, item) => ({ - link: new URL($(item).find('div.content > h3.h5 > a').attr('href'), host).href, - title: $(item).find('div.content > h3.h5 > a').text(), - author: $(item).find('span.name').text(), - })) - .get(); + const list = parseList(apiResponse.rows); - const items = await Promise.all( - list.map((item) => - ctx.cache.tryGet(item.link, async () => { - const detailResponse = await got(item.link); - const content = cheerio.load(detailResponse.data); + const acwScV2Cookie = await acw_sc__v2(list[0].link, ctx.cache.tryGet); - item.description = content('article') - .html() - .replace(/data-src="/g, `src="${host}`); - item.pubDate = parseDate(content('time').attr('datetime')); - - return item; - }) - ) - ); + const items = await Promise.all(list.map((item) => parseItems(acwScV2Cookie, item, ctx.cache.tryGet))); ctx.state.data = { - title: `segmentfault - ${channel_name}`, + title: `segmentfault - ${channelName}`, link, item: items, }; diff --git a/lib/v2/segmentfault/user.js b/lib/v2/segmentfault/user.js index 2ea5510c0..636d37498 100644 --- a/lib/v2/segmentfault/user.js +++ b/lib/v2/segmentfault/user.js @@ -1,45 +1,19 @@ const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const { acw_sc__v2 } = require('./utils'); -const host = 'https://segmentfault.com'; +const { host, acw_sc__v2, parseList, parseItems } = require('./utils'); module.exports = async (ctx) => { - const name = ctx.params.name; - const apiURL = `https://segmentfault.com/gateway/homepage/${name}/timeline?size=20&offset=`; + const { name } = ctx.params; + const apiURL = `${host}/gateway/homepage/${name}/timeline?size=20&offset=`; const response = await got(apiURL); const data = response.data.rows; - const author = data[0].user.name; - const list = data.map((item) => ({ - title: item.title, - description: item.excerpt, - link: new URL(item.url, host).href, - author, - })); + const list = parseList(data); + const { author } = list[0]; const acwScV2Cookie = await acw_sc__v2(list[0].link, ctx.cache.tryGet); - const items = await Promise.all( - list.map((item) => - ctx.cache.tryGet(item.link, async () => { - const response = await got(item.link, { - headers: { - cookie: `acw_sc__v2=${acwScV2Cookie};`, - }, - }); - const content = cheerio.load(response.data); - - item.description = content('article') - .html() - .replace(/data-src="/g, `src="${host}`); - item.pubDate = parseDate(content('time').attr('datetime')); - - return item; - }) - ) - ); + const items = await Promise.all(list.map((item) => parseItems(acwScV2Cookie, item, ctx.cache.tryGet))); ctx.state.data = { title: `segmentfault - ${author}`, diff --git a/lib/v2/segmentfault/utils.js b/lib/v2/segmentfault/utils.js index 463b2a914..bf19c3e8a 100644 --- a/lib/v2/segmentfault/utils.js +++ b/lib/v2/segmentfault/utils.js @@ -1,8 +1,12 @@ const zlib = require('zlib'); const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); const config = require('@/config').value; const { getAcwScV2ByArg1 } = require('@/v2/5eplay/utils'); +const host = 'https://segmentfault.com'; + const acw_sc__v2 = (link, tryGet) => tryGet( 'segmentfault:acw_sc__v2', @@ -29,6 +33,34 @@ const acw_sc__v2 = (link, tryGet) => false ); +const parseList = (data) => + data.map((item) => ({ + title: item.title, + link: new URL(item.url, host).href, + author: item.user.name, + pubDate: parseDate(item.created, 'X'), + })); + +const parseItems = (cookie, item, tryGet) => + tryGet(item.link, async () => { + const response = await got(item.link, { + headers: { + cookie: `acw_sc__v2=${cookie};`, + }, + }); + const content = cheerio.load(response.data); + + item.description = content('article').html(); + item.category = content('.badge-tag') + .toArray() + .map((item) => content(item).text()); + + return item; + }); + module.exports = { + host, acw_sc__v2, + parseList, + parseItems, }; diff --git a/website/docs/routes/programming.md b/website/docs/routes/programming.md index e974846c2..caec71136 100644 --- a/website/docs/routes/programming.md +++ b/website/docs/routes/programming.md @@ -826,7 +826,7 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News -## segmentfault {#segmentfault} +## SegmentFault {#segmentfault} ### 频道 {#segmentfault-pin-dao} @@ -838,7 +838,7 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News ### 博客 {#segmentfault-bo-ke} - + ## Smashing Magazine {#smashing-magazine}