fix: smzdm

This commit is contained in:
DIYgod 2025-05-29 12:51:04 +08:00
parent 645c202308
commit 44aba27033
No known key found for this signature in database
9 changed files with 291 additions and 170 deletions

View File

@ -401,6 +401,9 @@ export type Config = {
zsxq: {
accessToken?: string;
};
smzdm: {
cookie?: string;
};
};
const value: Config | Record<string, any> = {};
@ -842,6 +845,9 @@ const calculateValue = () => {
zsxq: {
accessToken: envs.ZSXQ_ACCESS_TOKEN,
},
smzdm: {
cookie: envs.SMZDM_COOKIE,
},
};
for (const name in _value) {

View File

@ -4,6 +4,9 @@ import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
import { config } from '@/config';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/article/:uid',
@ -11,7 +14,12 @@ export const route: Route = {
example: '/smzdm/article/6902738986',
parameters: { uid: '用户 id网址上直接可以看到' },
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -29,9 +37,15 @@ 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 got(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const title = $('.info-stuff-nickname a').text();
@ -49,7 +63,9 @@ async function handler(ctx) {
const out = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
const response = await got(item.link);
const response = await got(item.link, {
headers: getHeaders(),
});
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);

View File

@ -4,6 +4,9 @@ import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
import { config } from '@/config';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/baoliao/:uid',
@ -11,7 +14,12 @@ export const route: Route = {
example: '/smzdm/baoliao/7367111021',
parameters: { uid: '用户id网址上直接可以看到' },
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -29,9 +37,15 @@ 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 got(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const title = $('.info-stuff-nickname').text();
@ -49,7 +63,9 @@ async function handler(ctx) {
const out = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
const response = await got(item.link);
const response = await got(item.link, {
headers: getHeaders(),
});
const $ = load(response.data);
item.description = $('article.txt-detail').html();
item.pubDate = timezone(parseDate($('.time').first().text().trim().replace('更新时间:', '')), 8);

View File

@ -4,13 +4,21 @@ import got from '@/utils/got';
import { load } from 'cheerio';
import timezone from '@/utils/timezone';
import { parseDate } from '@/utils/parse-date';
import { config } from '@/config';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/haowen/fenlei/:name/:sort?',
categories: ['shopping'],
example: '/smzdm/haowen/fenlei/shenghuodianqi',
parameters: { name: '分类名,可在 URL 中查看', sort: '排序方式,默认为最新' },
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -32,12 +40,18 @@ 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 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 response = await got.get(link);
const response = await got.get(link, {
headers: getHeaders(),
});
const $ = load(response.data);
const title = $('div.crumbs.nav-crumbs').text().split('>').pop();
@ -58,7 +72,9 @@ async function handler(ctx) {
list.map((item) =>
cache.tryGet(item.link, async () => {
try {
const response = await got(item.link);
const response = await got(item.link, {
headers: getHeaders(),
});
const $ = load(response.data);
item.description = $('article').html();
item.pubDate = timezone(parseDate($('meta[property="og:release_date"]').attr('content')), 8);

View File

@ -4,6 +4,9 @@ import ofetch from '@/utils/ofetch';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import { config } from '@/config';
export const route: Route = {
path: '/haowen/:day?',
@ -21,7 +24,12 @@ export const route: Route = {
},
},
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -34,10 +42,16 @@ 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 day = ctx.req.param('day') ?? '1';
const link = `https://post.smzdm.com/hot_${day}/`;
const response = await ofetch(link);
const response = await ofetch(link, {
headers: getHeaders(),
});
const $ = load(response);
const title = $('li.filter-tab.active').text();
@ -55,7 +69,9 @@ async function handler(ctx) {
const out = await Promise.all(
list.map((item) =>
cache.tryGet(item.link ?? '', async () => {
const response = await ofetch(item.link ?? '');
const response = await ofetch(item.link ?? '', {
headers: getHeaders(),
});
const $ = load(response);
const content = $('#articleId');
content.find('.item-name').remove();

View File

@ -3,6 +3,9 @@ import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import { config } from '@/config';
export const route: Route = {
path: '/keyword/:keyword',
@ -11,7 +14,12 @@ export const route: Route = {
example: '/smzdm/keyword/女装',
parameters: { keyword: '你想订阅的关键词' },
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -24,10 +32,15 @@ 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 keyword = ctx.req.param('keyword');
const response = await got(`https://search.smzdm.com`, {
headers: {
...getHeaders(),
Referer: `https://search.smzdm.com/?c=home&s=${encodeURIComponent(keyword)}&order=time&v=a`,
},
searchParams: {

View File

@ -2,6 +2,9 @@ import { Route, DataItem } from '@/types';
import ofetch from '@/utils/ofetch';
import { load } from 'cheerio';
import cache from '@/utils/cache';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import { config } from '@/config';
export const route: Route = {
path: '/product/:id',
@ -9,7 +12,12 @@ export const route: Route = {
example: '/smzdm/product/zm5vzpe',
parameters: { id: '商品 id网址上直接可以看到' },
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -28,9 +36,15 @@ 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://wiki.smzdm.com/p/${ctx.req.param('id')}`;
const response = await ofetch(link);
const response = await ofetch(link, {
headers: getHeaders(),
});
const $ = load(response);
const title = $('title').text();
@ -55,7 +69,9 @@ async function handler(ctx) {
const out = await Promise.all(
items.map((item) =>
cache.tryGet(item.link, async () => {
const response = await ofetch(item.link);
const response = await ofetch(item.link, {
headers: getHeaders(),
});
const $ = load(response);
// filter outdated articles

View File

@ -1,6 +1,9 @@
import { config } from '@/config';
import { Route, ViewType } from '@/types';
import got from '@/utils/got';
import timezone from '@/utils/timezone';
import { getHeaders } from './utils';
import ConfigNotFoundError from '@/errors/types/config-not-found';
const getTrueHour = (rank_type, rank_id, hour) => {
const rank_two_hour = ['11', '17', '28', '29'];
@ -13,6 +16,159 @@ const getTrueHour = (rank_type, rank_id, hour) => {
}
};
const typeOptions = [
{
value: 'pinlei',
label: '好价品类榜',
},
{
value: 'dianshang',
label: '好价电商榜',
},
{
value: 'haitao',
label: '海淘 TOP 榜',
},
{
value: 'haowen',
label: '好文排行榜',
},
{
value: 'haowu',
label: '好物排行榜',
},
];
const idOptions = [
{
label: '好价品类榜-全部',
value: '11',
},
{
label: '好价品类榜-食品生鲜',
value: '12',
},
{
label: '好价品类榜-电脑数码',
value: '13',
},
{
label: '好价品类榜-运动户外',
value: '14',
},
{
label: '好价品类榜-家用电器',
value: '15',
},
{
label: '好价品类榜-白菜',
value: '17',
},
{
label: '好价品类榜-服饰鞋包',
value: '74',
},
{
label: '好价品类榜-日用百货',
value: '75',
},
{
label: '好价电商榜-券活动',
value: '24',
},
{
label: '好价电商榜-京东',
value: '23',
},
{
label: '好价电商榜-天猫',
value: '25',
},
{
label: '好价电商榜-亚马逊中国',
value: '26',
},
{
label: '好价电商榜-国美在线',
value: '27',
},
{
label: '好价电商榜-苏宁易购',
value: '28',
},
{
label: '好价电商榜-网易',
value: '29',
},
{
label: '好价电商榜-西集网',
value: '30',
},
{
label: '好价电商榜-美国亚马逊',
value: '31',
},
{
label: '好价电商榜-日本亚马逊',
value: '32',
},
{
label: '好价电商榜-ebay',
value: '33',
},
{
label: '海淘 TOP 榜-全部',
value: '39',
},
{
label: '海淘 TOP 榜-海外直邮',
value: '34',
},
{
label: '海淘 TOP 榜-美国榜',
value: '35',
},
{
label: '海淘 TOP 榜-欧洲榜',
value: '36',
},
{
label: '海淘 TOP 榜-澳新榜',
value: '37',
},
{
label: '海淘 TOP 榜-亚洲榜',
value: '38',
},
{
label: '海淘 TOP 榜-晒物榜',
value: 'hsw',
},
{
label: '好文排行榜-原创',
value: 'yc',
},
{
label: '好文排行榜-资讯',
value: 'zx',
},
{
label: '好物排行榜-新晋榜',
value: 'hwall',
},
{
label: '好物排行榜-消费众测',
value: 'zc',
},
{
label: '好物排行榜-新锐品牌',
value: 'nb',
},
{
label: '好物排行榜-好物榜单',
value: 'hw',
},
];
export const route: Route = {
path: '/ranking/:rank_type/:rank_id/:hour',
categories: ['shopping', 'popular'],
@ -21,161 +177,11 @@ export const route: Route = {
parameters: {
rank_type: {
description: '榜单类型',
options: [
{
value: 'pinlei',
label: '好价品类榜',
},
{
value: 'dianshang',
label: '好价电商榜',
},
{
value: 'haitao',
label: '海淘 TOP 榜',
},
{
value: 'haowen',
label: '好文排行榜',
},
{
value: 'haowu',
label: '好物排行榜',
},
],
options: typeOptions,
},
rank_id: {
description: '榜单ID',
options: [
{
label: '好价品类榜 - 全部',
value: '11',
},
{
label: '好价品类榜 - 食品生鲜',
value: '12',
},
{
label: '好价品类榜 - 电脑数码',
value: '13',
},
{
label: '好价品类榜 - 运动户外',
value: '14',
},
{
label: '好价品类榜 - 家用电器',
value: '15',
},
{
label: '好价品类榜 - 白菜',
value: '17',
},
{
label: '好价品类榜 - 服饰鞋包',
value: '74',
},
{
label: '好价品类榜 - 日用百货',
value: '75',
},
{
label: '好价电商榜 - 券活动',
value: '24',
},
{
label: '好价电商榜 - 京东',
value: '23',
},
{
label: '好价电商榜 - 天猫',
value: '25',
},
{
label: '好价电商榜 - 亚马逊中国',
value: '26',
},
{
label: '好价电商榜 - 国美在线',
value: '27',
},
{
label: '好价电商榜 - 苏宁易购',
value: '28',
},
{
label: '好价电商榜 - 网易',
value: '29',
},
{
label: '好价电商榜 - 西集网',
value: '30',
},
{
label: '好价电商榜 - 美国亚马逊',
value: '31',
},
{
label: '好价电商榜 - 日本亚马逊',
value: '32',
},
{
label: '好价电商榜 - ebay',
value: '33',
},
{
label: '海淘 TOP 榜 - 全部',
value: '39',
},
{
label: '海淘 TOP 榜 - 海外直邮',
value: '34',
},
{
label: '海淘 TOP 榜 - 美国榜',
value: '35',
},
{
label: '海淘 TOP 榜 - 欧洲榜',
value: '36',
},
{
label: '海淘 TOP 榜 - 澳新榜',
value: '37',
},
{
label: '海淘 TOP 榜 - 亚洲榜',
value: '38',
},
{
label: '海淘 TOP 榜 - 晒物榜',
value: 'hsw',
},
{
label: '好文排行榜 - 原创',
value: 'yc',
},
{
label: '好文排行榜 - 资讯',
value: 'zx',
},
{
label: '好物排行榜 - 新晋榜',
value: 'hwall',
},
{
label: '好物排行榜 - 消费众测',
value: 'zc',
},
{
label: '好物排行榜 - 新锐品牌',
value: 'nb',
},
{
label: '好物排行榜 - 好物榜单',
value: 'hw',
},
],
options: idOptions,
},
hour: {
description: '时间跨度',
@ -196,7 +202,12 @@ export const route: Route = {
},
},
features: {
requireConfig: false,
requireConfig: [
{
name: 'SMZDM_COOKIE',
description: '什么值得买登录后的 Cookie 值',
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
@ -209,6 +220,10 @@ 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 { rank_type, rank_id, hour } = ctx.req.param();
// When the hour is 3, some special rank_id require a special hour num
@ -217,6 +232,7 @@ async function handler(ctx) {
const response = await got(`https://www.smzdm.com/top/json_more`, {
headers: {
Referer: 'https://www.smzdm.com/top/',
...getHeaders(),
},
searchParams: {
rank_type,
@ -239,7 +255,7 @@ async function handler(ctx) {
const list = [...list1, ...list2];
return {
title: `${rank_type}-${rank_id}-${hour}小时`,
title: `什么值得买${typeOptions.find((item) => item.value === rank_type)?.label}-${idOptions.find((item) => item.value === rank_id)?.label}-${hour}小时`,
link: 'https://www.smzdm.com/top/',
allowEmpty: true,
item: list.map((item) => ({

View File

@ -0,0 +1,6 @@
import { config } from '@/config';
export const getHeaders = () => ({
cookie: config.smzdm.cookie,
'x-requested-with': 'XMLHttpRequest',
});