zoukankan      html  css  js  c++  java
  • nodejs:使用puppeteer在服务器中构建一个获取电影电视剧剧集的接口

    首先我们看下数据来源:

    来源于这个网站:https://z1.m1907.cn/

    可以说这个网站上能找到很多你想看的很多电影或电视剧,最重要的是很多电影电视剧在别的网站是收费的,但是在这里看是免费的,之前也经常在这个网站中看。

    不过这个网站有些缺点:在微信中被屏蔽了网址。在夸克浏览器上如果播放到某集,夸克播放器就会覆盖掉原生播放器,导致切换下一集时不好切换过去,因此,希望能开发一个自己的网站,获取该网站的数据来呈现。

     

    一般来说,我们只需要拿到这些数据的url接口就行了。但是看了这个网站的network请求,发现这个接口的某个参数是可变的,而且还是必须要的。

    这个url就算获取视频列表的接口,但是中间的z参数是必填的,而且每过一段时间就需要更换参数。

    这个参数它不来源于上一个接口的某个结果,它是通过js进行了md5之后生成的。这就难办了。怎么去获取这个值呢?

    我们点击这里,然后点击这个小图标

    断点发现,生成z参数的就是这个p变量

    然后,因为内部代码已被压缩,所以不好理清楚里面的逻辑了,所以就采用了fiddler抓包工具,将这个js文件进行代理到本地js中。篡改js文件做一些外加功能。

    我使用fiddler代理篡改了这段代码,就是将这个z参数显示在dom中

    因此,dom中就有了这么一个dom元素,那么这有什么用呢?这样我就能在自己的服务器中拿到这个值?

    是的,我使用的是nodejs。前段时间在网上找到了一个有意思npm包,用来在服务器中模拟浏览器操作,自然在服务器中就能获取到浏览器中渲染的dom了。那就是标题里说的puppeteer。

    因为之前用fiddler代理将这个只放在了dom中,因此我们也就可以使用puppeteer模块从dom中拿到这个值,曲线救国。

     

    请看实现(使用koajs服务端,ctx.response.body即可输出这个z参数)

    const puppeteer = require('puppeteer');
    /**
     * 获取https://z1.m1907.cn/的动态z 需求开fiddler
     */
    module.exports = async(ctx) => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://z1.m1907.cn/?jx=bilibili');
        //注入脚本
        const dimensions = await page.evaluate(async() => {
            let z = ''
            if (document.querySelector('#z')) {
                z = document.querySelector('#z').innerText;
            }
            return {
                z,
            }
        });
        await browser.close();
        ctx.response.body = dimensions;
        return dimensions;//这个return是给下一个接口调用的
    }

    page.evaluate可以将浏览器的js代码注入到dimensions的隐藏浏览器中。就能通过document.querySelector('#z').innerText拿到那个z参数,然后通过node返回了。

    拿到了。这个数据一般能使用几个小时,几个小时后又需要重新获取新的值了,重新执行接口即可。

     

    拿到这样要获取数据就容易多了。

    看后续写法:

    const { loadPage } = require('../../utils/utils');
    const getId = require('./getId');
    const setting = require('./setting');
    
    /**
     * 主程序
     */
    const videos = async(ctx) => {
        const { title = 'bilibili', z = null } = ctx.query
            // console.log(setting.z)
        z && (setting.z = z); //手动输入z参数
        const content = await loadPage(`https://a1.m1907.cn/api/v/?z=${setting.z}&jx=${title}&s1ig=11402&g=`);
        if (content.includes('获取json版api地址')) {//获取数据错误 重新获取z参数
            const obj = await getId(ctx);
            console.log(obj)
            setting.z = obj.z
            await videos(ctx)
            return;
        }
        ctx.response.body = content;
    }
    
    module.exports = videos;

    loadPage是封装的请求页面的方法,getId是之前用于返回z参数的方法,setting是用于储存获取到的z参数,失效了才重新获取。

    这样就能返回数据了。

    访问接口,拿到当前电视剧/电影的所有剧集的m3u8播放地址,这样在支持m3u8的播放器中就可以直接播放了。

    (完)

     

     

    朋友,看到这里,用支付宝扫码领个红包吧!实体店付款可以优惠哦!

    请认准【http://wuhairui.cnblogs.com/】

  • 相关阅读:
    八、UIViewController们之间的协作——Segue
    七、UIViewController导航栏
    六、APP开发的主角——UIViewController
    五、UI开发之核心基础——约束(深入)
    四、UI开发之核心基础——约束(实用)
    三、UI开发之核心基础——约束(入门)
    iOS开发笔记错误集
    Unity中内嵌网页插件UniWebView使用总结
    利用Aspose.Word控件实现Word文档的操作
    ReSharper 配置及用法(ZHUANG)
  • 原文地址:https://www.cnblogs.com/wuhairui/p/15497433.html
Copyright © 2011-2022 走看看