Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion lib/routes/mafengwo/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const generateWTsfp = (url: string) => {
loadts: now,
fingerprint,
abnormal: '0'.repeat(32),
referer: encodeURIComponent('https://www.mafengwo.cn/'),
referer: encodeURIComponent(`${new URL(url).origin}/`),
uri: encodeURIComponent(url),
checksum: md5(url + fingerprint + salt + now),
});
Expand Down
53 changes: 31 additions & 22 deletions lib/routes/smzdm/article.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { load } from 'cheerio';
import pMap from 'p-map';

import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';

Expand All @@ -19,6 +18,7 @@ export const route: Route = {
requireConfig: [
{
name: 'SMZDM_COOKIE',
optional: true,
description: '什么值得买登录后的 Cookie 值',
},
],
Expand All @@ -39,47 +39,56 @@ export const route: Route = {
};

async function handler(ctx) {
if (!config.smzdm.cookie) {
throw new ConfigNotFoundError('什么值得买排行榜 is disabled due to the lack of SMZDM_COOKIE');
}

const link = `https://zhiyou.smzdm.com/member/${ctx.req.param('uid')}/article/`;

const response = await got(link, {
const response = await ofetch.raw(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const cookie = getHeaders().cookie || [...response.headers.getSetCookie().map((c) => c.split(';', 1)[0]), `x-waf-captcha-referer=${link}`].join('; ');
const $ = load(response._data);
const title = $('.info-stuff-nickname a').text();

const list = $('.pandect-content-stuff')
const list = $('.pandect-content-common')
.toArray()
.map((item): DataItem => {
const $item = $(item);
const a = $item.find('.pandect-content-title a');
return {
title: $item.find('.pandect-content-title a').text(),
link: $item.find('.pandect-content-title a').attr('href'),
title: a.text(),
description: $item.find('.pandect-content-detail').text(),
link: a.attr('href'),
pubDate: timezone(parseDate($item.find('.pandect-content-time').text(), ['YYYY-MM-DD', 'MM-DD HH:mm']), 8),
image: $item.find('.pandect-content-img img').attr('src'),
};
});

const out = await Promise.all(
list.map((item) =>
const out = await pMap(
list,
(item) =>
cache.tryGet(item.link!, async () => {
const response = await got(item.link, {
headers: getHeaders(),
const response = await ofetch(item.link!, {
headers: {
cookie,
},
});
const $ = load(response.data);
item.description = $('.m-contant article').html();
item.pubDate = timezone(parseDate($('meta[property="og:release_date"]').attr('content')!, 'YYYY-MM-DD HH:mm:ss'), 8);
item.author = $('meta[property="og:author"]').attr('content');
const $ = load(response);
const article = $('.m-contant article');
article.find('h1, .recommend-tab, input, .the-end').remove();
item.description = article.html() ?? item.description;
const ldJson = JSON.parse($('script[type="application/ld+json"]:contains("datePublished")').text() || '{}');
item.pubDate = $('meta[property="og:release_date"]').length ? timezone(parseDate($('meta[property="og:release_date"]').attr('content')!, 'YYYY-MM-DD HH:mm:ss'), 8) : item.pubDate;
item.author = ldJson.author?.name;
item.category = [...(ldJson.about?.map((a) => a.name) || []), ...(ldJson.mentions?.map((m) => m.name) || [])];

return item;
})
)
}),
{ concurrency: 3 }
);

return {
title: `${title}-什么值得买`,
description: $('.info-stuff-words div').text(),
image: `https:${$('.avatar-img').attr('src')}`,
link,
item: out,
};
Expand Down
36 changes: 19 additions & 17 deletions lib/routes/smzdm/baoliao.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { load } from 'cheerio';
import pMap from 'p-map';

import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';

Expand All @@ -19,6 +18,7 @@ export const route: Route = {
requireConfig: [
{
name: 'SMZDM_COOKIE',
optional: true,
description: '什么值得买登录后的 Cookie 值',
},
],
Expand All @@ -39,16 +39,13 @@ export const route: Route = {
};

async function handler(ctx) {
if (!config.smzdm.cookie) {
throw new ConfigNotFoundError('什么值得买排行榜 is disabled due to the lack of SMZDM_COOKIE');
}

const link = `https://zhiyou.smzdm.com/member/${ctx.req.param('uid')}/baoliao/`;

const response = await got(link, {
const response = await ofetch.raw(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const cookie = getHeaders().cookie || [...response.headers.getSetCookie().map((c) => c.split(';', 1)[0]), `x-waf-captcha-referer=${link}`].join('; ');
const $ = load(response._data);
const title = $('.info-stuff-nickname').text();

const list = $('.pandect-content-stuff')
Expand All @@ -62,24 +59,29 @@ async function handler(ctx) {
};
});

const out = await Promise.all(
list.map((item) =>
const out = await pMap(
list,
(item) =>
cache.tryGet(item.link!, async () => {
const response = await got(item.link, {
headers: getHeaders(),
const response = await ofetch(item.link!, {
headers: {
cookie,
},
});
const $ = load(response.data);
const $ = load(response);
item.description = $('article.txt-detail').html();
item.pubDate = timezone(parseDate($('.time').first().text().trim().replace('更新时间:', '')), 8);
item.pubDate = timezone(parseDate($('.time').text().replace('更新时间:', '')), 8);
item.author = title;

return item;
})
)
}),
{ concurrency: 3 }
);

return {
title: `${title}的爆料 - 什么值得买`,
description: $('.info-stuff-words div').text(),
image: `https:${$('.avatar-img').attr('src')}`,
link,
item: out,
};
Expand Down
75 changes: 35 additions & 40 deletions lib/routes/smzdm/haowen-fenlei.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { load } from 'cheerio';
import pMap from 'p-map';

import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import type { Route } from '@/types';
import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';

import { getHeaders } from './utils';

export const route: Route = {
path: '/haowen/fenlei/:name/:sort?',
path: '/haowen/fenlei/:name',
categories: ['shopping'],
example: '/smzdm/haowen/fenlei/shenghuodianqi',
parameters: { name: '分类名,可在 URL 中查看', sort: '排序方式,默认为最新' },
parameters: { name: '分类名,可在 URL 中查看' },
features: {
requireConfig: [
{
name: 'SMZDM_COOKIE',
optional: true,
description: '什么值得买登录后的 Cookie 值',
},
],
Expand All @@ -30,69 +30,64 @@ export const route: Route = {
},
radar: [
{
source: ['post.smzdm.com/fenlei/:name'],
source: ['www.smzdm.com/fenlei/:name'],
target: '/haowen/fenlei/:name',
},
],
name: '好文分类',
maintainers: ['LogicJake'],
handler,
description: `| 最新 | 周排行 | 月排行 |
| ---- | ------ | ------ |
| 0 | 7 | 30 |`,
};

async function handler(ctx) {
if (!config.smzdm.cookie) {
throw new ConfigNotFoundError('什么值得买排行榜 is disabled due to the lack of SMZDM_COOKIE');
}

const name = ctx.req.param('name');
const sort = ctx.req.param('sort') || '0';

const link = sort === '0' ? `https://post.smzdm.com/fenlei/${name}/` : `https://post.smzdm.com/fenlei/${name}/hot_${sort}/`;
const link = `https://www.smzdm.com/fenlei/${name}/`;

const response = await got.get(link, {
const response = await ofetch.raw(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const title = $('div.crumbs.nav-crumbs').text().split('>').pop();
const cookie = getHeaders().cookie || [...response.headers.getSetCookie().map((c) => c.split(';', 1)[0]), `x-waf-captcha-referer=${link}`].join('; ');
const $ = load(response._data);
const title = $('title').text().split('_', 1)[0];

const list = $('div.list.post-list')
.toArray()
.map((item) => {
const $item = $(item);
return {
title: $item.find('h2.item-name a').text(),
link: $item.find('h2.item-name a').attr('href'),
description: $item.find('.item-info').html(),
author: $item.find('.nickname').text(),
pubDate: timezone(parseDate($item.find('span.time').text(), ['HH:mm', 'MM-DD HH:mm', 'YYYY-MM-DD HH:mm']), 8),
};
});
const payload = JSON.parse($('#__NUXT_DATA__').text());
const list: DataItem[] = payload
.filter((entry) => entry instanceof Object && 'article_title' in entry && 'article_no_format_date' in entry)
.map((entry) => ({
title: payload[entry.article_title],
link: payload[entry.article_url],
description: payload[entry.article_content],
image: payload[entry.article_pic],
category: [payload[entry.article_channel_name], ...(payload[entry.article_tag] ?? []).map((tag) => payload[payload[tag].article_title])],
pubDate: timezone(parseDate(payload[entry.article_no_format_date]), 8),
}));

const out = await Promise.all(
list.map((item) =>
const out = await pMap(
list,
(item) =>
cache.tryGet(item.link!, async () => {
try {
const response = await got(item.link, {
headers: getHeaders(),
const response = await ofetch(item.link!, {
headers: {
cookie,
},
});
const $ = load(response.data);
item.description = $('article').html();
const $ = load(response);
item.description = $('article').html() ?? item.description;
item.pubDate = timezone(parseDate($('meta[property="og:release_date"]').attr('content')!), 8);
item.author = $('meta[property="og:author"]').attr('content')!;
} catch {
// 404
}

return item;
})
)
}),
{ concurrency: 3 }
);

return {
title: `${title}- 什么值得买好文分类`,
image: $('.avatar-img').attr('src'),
link,
item: out,
};
Expand Down
Loading
Loading