樱&花动漫接口逆向
-
-
This post is deleted! -
更新: 爬虫示例代码
export const config = { fetchHeader: { "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', "Dnt": '1', "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0" } } export interface VideoInfo { url: string // type: string } export abstract class Parser { public abstract parse(raw: string): Promise<VideoInfo> } import fetch from 'node-fetch' import * as cookie from 'cookie' const exp = /www\.yhmgo\.com\/vp\/(\d+)-(\d+)-(\d+)/ const API_BASE = 'https://www.yhmgo.com/playurl' const PAGE_BASE = 'https://www.yhmgo.com/vp' export class YhmgoParser extends Parser { async parse(url: string): Promise<VideoInfo> { const [match, id, channel, ep] = url.match(exp) if (!match) { throw new Error('Invalid url') } const pageUrl = `${PAGE_BASE}/${id}-${channel}-${ep}.html` const page = await fetch(pageUrl) let {t1, k1} = page.headers.raw()['set-cookie'].reduce((obj, str) => { return {...cookie.parse(str), ...obj} }, {}) let cookies = parseCookie(t1, k1) const raw = await fetch( `${API_BASE}?aid=${id}&playindex=${channel}&epindex=${ep}&r=${Math.random()}`, { headers: { ...config.fetchHeader, referer: pageUrl, cookie: Object.entries(cookies) .map(c => cookie.serialize(c[0], c[1])) .join('; ') } } ) const {vurl} = parseResult(await raw.text()) return { url: decodeURIComponent(vurl), // type: 'm3u8', } } } export function parseCookie(t1: number, k1: number) { let pos = Math.floor(t1 / 0x3e8) >> 0x5 let offset = 0x89a4 let k2 = '' + (((((pos * (pos % 0x100) + 0x1) + offset) * ((pos % 0x80) + 0x1)) * ((pos % 0x10) + 0x1)) + pos) let t2 = '' while (true) { t2 = '' + Math.floor(new Date().getTime()) let tOffset = t2.slice(t2.length - 0x3) let kOffset = k2.slice(k2.length - 0x1) if (tOffset.indexOf(kOffset) >= 0x0) { break } } let start = 0x0 let timeOffset = Math.floor(new Date().getTime() / 0x3e8) >> (0x11 + start) let m2t = ((((timeOffset * 0x15 + 0x9a) * (((timeOffset % 0x40) + 0xd)) * ((timeOffset % 0x20) + 0x22) * ((timeOffset % 0x10) + 0x57)) * ((timeOffset % 0x8) + 0x41)) + 0x2ef) return { t1, k1, t2, k2, m2t } } export function parseResult(raw: string): { purl: string, vurl: string, inv: string } { let result = '' const offset = 0x619 const rawLength = raw.length for (let i = 0x0; i < rawLength; i += 0x2) { let temp = parseInt(raw[i] + raw[i + 1], 0x10) temp = ( (temp + 0x100000 - offset) - (((rawLength / 0x2) - 0x1) - (i / 0x2)) ) % 0x100 result = String.fromCharCode(temp) + result } return JSON.parse(result) }
使用
import {YhmgoParser} from "./parser/yhmgo"; const parser = new YhmgoParser() const video = await parser.parse('https://www.yhmgo.com/vp/11141-2-0.html') console.log(video) // 输出: { url: 'https://vip.lz-cdn16.com/20230317/13224_75d9217b/index.m3u8' }