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的播放器中就可以直接播放了。

(完)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM