RSSHub/lib/routes/t66y/post.js

154 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const cheerio = require('cheerio');
const got = require('@/utils/got');
const iconv = require('iconv-lite');
const url = require('url');
const base = 'http://www.t66y.com';
const got_ins = got.extend({
headers: {
Referer: base,
},
responseType: 'buffer',
});
function killViidii(originUrl) {
const decodeStr = /.*\?http/g;
const decodeSig = /______/g;
const jsSuffix = '&z';
const htmlSuffix = '&z';
const returnSuffix = 'return false';
if (originUrl.indexOf('viidii') !== -1) {
return originUrl.replace(decodeStr, 'http').replace(decodeSig, '.').replace(jsSuffix, '').replace(htmlSuffix, '').replace(returnSuffix, '');
} else {
return originUrl;
}
}
const sourceTimezoneOffset = -8;
function parseContent(htmlString) {
let $ = cheerio.load(htmlString, { decodeEntities: false });
let time = $('.tipad').text();
const regex = /\d{4}-\d{2}-\d{2} \d{2}:\d{2}/;
const regRes = regex.exec(time);
time = regRes === null ? new Date() : new Date(regRes[0]);
time.setTime(time.getTime() + (sourceTimezoneOffset - time.getTimezoneOffset() / 60) * 60 * 60 * 1000);
const author = $('th.r_two > b').text();
const content = $('.tpc_content').html();
// Change the image tag to display image in rss reader
try {
$ = cheerio.load(content, { decodeEntities: false }); // 修复无发进行filter与filterout的问题
} catch (error) {
return null;
}
// Handle video
const video = $('a:nth-of-type(2)');
if (video) {
const videoScript = video.attr('onclick');
const regVideo = /https?:\/\/.*'/;
const videoRes = regVideo.exec(videoScript);
if (videoRes && videoRes.length !== 0) {
let link = videoRes[0];
link = link.slice(0, link.length - 1);
$('iframe').attr('src', link);
}
}
// Handle img tag
let images = $('img');
for (let k = 0; k < images.length; k++) {
$(images[k]).replaceWith(`<img src="${$(images[k]).attr('data-src')}" />`);
}
// Handle input tag
images = $('input');
for (let k = 0; k < images.length; k++) {
$(images[k]).replaceWith(`<img src="${$(images[k]).attr('data-src')}" />`);
}
// Handle links
const links = $('a[href*="viidii"]');
for (let k = 0; k < links.length; k++) {
$(links[k]).attr('href', killViidii($(links[k]).attr('href')));
}
return {
author,
description: $('body').html(),
pubDate: time.toUTCString(),
};
}
module.exports = async (ctx) => {
const tid = ctx.params.tid;
let response = await got_ins.get(url.resolve(base, `/read.php?tid=${tid}`));
let html = iconv.decode(response.data, 'gbk');
// 跟踪重定向
let $ = cheerio.load(html);
const redirect = $('a:last-child').attr('href');
response = await got_ins.get(url.resolve(base, redirect));
html = iconv.decode(response.data, 'gbk');
$ = cheerio.load(html, { decodeEntities: false });
// 获取楼主id、末页
const uid = /uid=(\d+)/.exec($('.t.t2').first().find('.tiptop>a:first-child').attr('href'))[1];
const lasturl = $('.pages:first-child>a:last-child').attr('href');
const lastpage = lasturl ? /page=(\d+)/.exec(lasturl)[1] : 1;
// 从缓存中获取上次读取的页吗
let page = 0;
const cachePage = await ctx.cache.tryGet(`/t66y/post/${tid}`, () => ({ page }));
page = cachePage.page + 1;
if (page > lastpage) {
page = lastpage;
}
// 记录重试次数
let retry = 0;
// 请求帖子
const load = async (page) => {
const link = url.resolve(base, `/read.php?tid=${tid}&page=${page}`);
if (page > 1) {
// 只有第二页开始需要重新读取
html = await ctx.cache.tryGet(link, async () => {
const response = await got_ins.get(link, {
headers: {
Referer: url.resolve(base, redirect),
},
});
return iconv.decode(response.data, 'gbk');
});
$ = cheerio.load(html, { decodeEntities: false });
}
const title = /本頁主題: (.+)\n?/.exec($('#main div.t .h:first-child').text())[1];
const items = $('.t.t2')
.get()
.filter((item) => {
const matchs = /uid=(\d+)/.exec($('.tiptop>a:first-child', item).attr('href'));
return matchs.length === 2 && uid === matchs[1];
})
.map((item, index) => {
const single = {
title: `P${page}#${index + 1} ${title}`,
link: `${link}#${index + 1}`,
guid: `${link}#${index + 1}`,
};
const result = parseContent($(item).html());
return Object.assign(single, result);
});
// 记录读取的最后页码
ctx.cache.set(`/t66y/post/${tid}`, JSON.stringify({ page }));
// 如果没有读到内容则读取下一页最多读取3页
if (items.length === 0 && retry < 3) {
retry++; // 记录重试次数
return load(page + 1);
} else {
return { title, link: url.resolve(base, `/read.php?tid=${tid}`), item: items };
}
};
ctx.state.data = await load(page);
};