155 lines
4.5 KiB
JavaScript
155 lines
4.5 KiB
JavaScript
const cheerio = require('cheerio');
|
|
const { parseDate } = require('@/utils/parse-date');
|
|
const got = require('@/utils/got');
|
|
const { art } = require('@/utils/render');
|
|
const path = require('path');
|
|
const CryptoJS = require('crypto-js');
|
|
|
|
const accountApi = 'https://account-api.huxiu.com';
|
|
const articleApi = 'https://api-article.huxiu.com';
|
|
const baseUrl = 'https://www.huxiu.com';
|
|
const briefApi = 'https://api-brief.huxiu.com';
|
|
const momentApi = 'https://moment-api.huxiu.com';
|
|
const searchApi = 'https://search-api.huxiu.com';
|
|
|
|
const ProcessFeed = (list, cache) =>
|
|
Promise.all(
|
|
list.map((item) =>
|
|
cache.tryGet(item.link, async () => {
|
|
const response = await got(item.link, {
|
|
https: {
|
|
rejectUnauthorized: false,
|
|
},
|
|
});
|
|
const $ = cheerio.load(response.data);
|
|
const initialState = parseInitialState($);
|
|
|
|
if (item.link.startsWith(`${baseUrl}/article/`)) {
|
|
fetchArticle(initialState, item);
|
|
} else if (item.link.startsWith(`${baseUrl}/brief/`)) {
|
|
fetchBrief(initialState, item);
|
|
}
|
|
|
|
return item;
|
|
})
|
|
)
|
|
);
|
|
|
|
const fetchArticle = (initialState, item) => {
|
|
const { articleDetail } = initialState.articleDetail;
|
|
const topImg = art(path.join(__dirname, 'templates/img.art'), {
|
|
img: articleDetail.pic_path.split('?')[0],
|
|
});
|
|
let video = '';
|
|
if (articleDetail.video_info) {
|
|
video = art(path.join(__dirname, 'templates/video.art'), {
|
|
video_info: articleDetail.video_info,
|
|
});
|
|
}
|
|
|
|
const $ = cheerio.load(articleDetail.content, null, false);
|
|
|
|
$('.text-big-title').each((_, e) => (e.tagName = 'h3'));
|
|
fixImg($);
|
|
removeExtraLinebreak($);
|
|
// $('img.dialog_add_wxxy_qrcode_icon').remove();
|
|
|
|
item.description = video + topImg + $.html();
|
|
item.author = articleDetail.author;
|
|
item.category = articleDetail.tags_info.map((tag) => tag.name);
|
|
};
|
|
|
|
const fetchBrief = (initialState, item) => {
|
|
const { brief_detail } = initialState.briefStoreModule;
|
|
const { brief_column } = brief_detail;
|
|
|
|
const description = art(path.join(__dirname, 'templates/brief.art'), {
|
|
brief: brief_detail.brief,
|
|
});
|
|
|
|
const $ = cheerio.load(description, null, false);
|
|
|
|
$('button.black-dot').remove();
|
|
fixImg($);
|
|
removeExtraLinebreak($);
|
|
|
|
item.description = $.html();
|
|
item.author = brief_detail.brief.publisher_list.map((item) => item.username).join(', ');
|
|
item.pubDate = parseDate(brief_column.update_time, 'X');
|
|
};
|
|
|
|
const parseInitialState = ($) =>
|
|
JSON.parse(
|
|
$('script')
|
|
.text()
|
|
.match(/window\.__INITIAL_STATE__=(\{.*?\});\(function\(\)/)[1]
|
|
);
|
|
|
|
const fixImg = ($) => {
|
|
$('img.lazyImg, img.js-preview').each((_, e) => {
|
|
if (e.attribs._src) {
|
|
e.attribs.src = e.attribs._src.split('?')[0];
|
|
delete e.attribs._src;
|
|
}
|
|
if (e.attribs.src.includes('?')) {
|
|
e.attribs.src = e.attribs.src.split('?')[0];
|
|
}
|
|
if (e.attribs['data-w']) {
|
|
e.attribs.width = e.attribs['data-w'];
|
|
delete e.attribs['data-w'];
|
|
}
|
|
if (e.attribs['data-h']) {
|
|
e.attribs.height = e.attribs['data-h'];
|
|
delete e.attribs['data-h'];
|
|
}
|
|
});
|
|
};
|
|
|
|
const removeExtraLinebreak = ($) => {
|
|
$('p').each((_, e) => {
|
|
e = $(e);
|
|
if (e.find('img').length === 0 && e.text().match(/^\s*$/)) {
|
|
e.remove();
|
|
}
|
|
});
|
|
};
|
|
|
|
const generateNonce = () => {
|
|
let nonce = '';
|
|
const e = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
const t = 16;
|
|
for (let i = 0; i < t; i++) {
|
|
nonce += e.charAt(Math.floor(Math.random() * e.length));
|
|
}
|
|
return nonce;
|
|
};
|
|
|
|
const generateSignature = () => {
|
|
const timestamp = Math.round(new Date().getTime() / 1000).toString();
|
|
// const appSecret = '4nHzGgGt7WX4zFTsTKocpxg4dzU6-wUi';
|
|
const appSecret = 'hUzaVKtNfDE-6UiyaJdfsmjW-8dwoyVc'; // appid: 'hx_search'
|
|
const nonce = generateNonce();
|
|
const r = [appSecret, timestamp, nonce].sort();
|
|
return {
|
|
nonce,
|
|
timestamp,
|
|
signature: CryptoJS.SHA1(r[0] + r[1] + r[2]).toString(),
|
|
};
|
|
};
|
|
|
|
module.exports = {
|
|
accountApi,
|
|
articleApi,
|
|
baseUrl,
|
|
briefApi,
|
|
momentApi,
|
|
searchApi,
|
|
ProcessFeed,
|
|
fetchArticle,
|
|
fetchBrief,
|
|
parseInitialState,
|
|
fixImg,
|
|
removeExtraLinebreak,
|
|
generateSignature,
|
|
};
|