MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接

    樱&花动漫接口逆向

    开发交流
    2
    3
    757
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • Dituon
      Dituon 最后由 Dituon 编辑

      想实现番剧下载的爬虫,花了两天时间逆向某知名动画网站的接口

      yhmgo.com

      https://github.com/Dituon/yhmgo-parser

      注意:悄悄滴使用,声张滴不要

      1 条回复 最后回复 回复 引用 1
      • Mr.喜
        Mr.喜 ⭐2021⭐ 最后由 编辑

        此回复已被删除!
        1 条回复 最后回复 回复 引用 0
        • Dituon
          Dituon 最后由 Dituon 编辑

          更新: 爬虫示例代码

          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' }
          
          1 条回复 最后回复 回复 引用 2
          • 1 / 1
          • First post
            Last post
          Powered by Mamoe Technologies & NodeBB | 友情链接 | 服务监控 | Contact