请问,为什么 puppeteer 向页面注入 jquery 代码, jquery 却不能立即起作用? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hgjian
V2EX    Node.js

请问,为什么 puppeteer 向页面注入 jquery 代码, jquery 却不能立即起作用?

  •  
  •   hgjian 2019-07-18 10:18:29 +08:00 6876 次点击
    这是一个创建于 2351 天前的主题,其中的信息可能已经有所发展或是发生改变。

    const puppeteer = require('puppeteer');

    void(async () => { const browser = await puppeteer.launch({ headless: false, devtools: true }); const page = await browser.newPage(); const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36"; // UserAgent ; await Promise.all ( [ page.setUserAgent ( UA ) , page.setJavascriptEnabled ( true ) , // 允许执行 js 脚本 ] ) ; await page.goto( "http://www.gewara.com/" , { waitUntil : "networkidle0" , timeout : 3600000 } ) ; await page .mainFrame() .addScriptTag({ url: 'https://code.jquery.com/jquery-3.4.1.min.js' }); await page.waitFor(2000); page.on( 'console' , msg => console.log( "var result = await page.evaluate( ( ) =>{ *** 函数内的 console.log:" , msg.text() ) ); const result = await page.evaluate(() => { const watchDog = ( window.$ !== undefined ); console.log( "window.$ !== undefined JQ:" + watchDog ) ; // 应该显示 true ;实际测试却显示 false ;但是,浏览器运行打开网页后,在控制面板测试,就显示为 true 了 ; return }); console.log(result); })(); 
    27 条回复    2019-07-26 23:32:09 +08:00
    hgjian
        1
    hgjian  
    OP
       2019-07-18 10:18:50 +08:00
    console.log( "window.$ !== undefined JQ:" + watchDog ) ; // 应该显示 true ;实际测试却显示 false ;但是,浏览器运行打开网页后,在控制面板测试,就显示为 true 了 ;
    2DaYe
        2
    2DaYe  
       2019-07-18 12:23:40 +08:00
    jQuery 库引用晚了吧?页面都 load 完了再引,jQuery 就没法初始化了吧?
    hgjian
        3
    hgjian  
    OP
       2019-07-18 12:35:34 +08:00
    @2DaYe 请问怎么解决啊?
    learnshare
        4
    /div> learnshare  
       2019-07-18 12:39:43 +08:00
    const page = await browser.newPage();

    await page.addScriptTag({
    path: './node_modules/jquery/dist/jquery.js',
    });

    await page.goto()
    hgjian
        5
    hgjian  
    OP
       2019-07-18 12:43:19 +08:00
    @learnshare 安装 jq 库?
    hgjian
        6
    hgjian  
    OP
       2019-07-18 15:07:44 +08:00
    @learnshare 你好,我按照你的代码试了一下,还是不行哦
    learnshare
        7
    learnshare  
       2019-07-18 16:00:10 +08:00
    @hgjian 大概你测试的网站不允许 jQuery,测试本站是可以的

    https://gist.github.com/LearnShare/2af03a1d6bcb41a9ec81b51e25435e3d
    hgjian
        8
    hgjian  
    OP
       2019-07-18 16:06:57 +08:00
    @learnshare 应该是可以的吧,puppeteer 打开 chrome 浏览器运行网页后,jquery 就生效了 ;
    learnshare
        9
    learnshare  
       2019-07-18 16:13:50 +08:00
    @hgjian 但实际测下来就是没有 $
    hgjian
        10
    hgjian  
    OP
       2019-07-18 16:26:56 +08:00
    @learnshare 那好奇怪啊,在浏览器控制台执行 window.$(".city-current").innerText 可以取得结果
    hgjian
        11
    hgjian  
    OP
       2019-07-18 16:27:42 +08:00
    我中间有成功过一次,后来改乱了,不知道成功的代码是什么样的了,
    Melting
        12
    Melting  
       2019-07-18 17:17:20 +08:00
    好像是因为 http 的关系,而且话说 chrome 命令行也有$这个命令,可能冲突了
    hgjian
        13
    hgjian  
    OP
       2019-07-18 17:25:44 +08:00
    @Melting 有什么解决办法吗?
    hgjian
        14
    hgjian  
    OP
       2019-07-18 17:26:26 +08:00
    @Melting 或者也没有什么办法可以判断页面的 js 是不是全部执行完毕了啊?
    shinpei
        15
    shinpei  
       2019-07-18 20:22:38 +08:00
    这个就涉及到 jQuery 源码的问题了;

    jquery 在代码尾部全局注册:
    if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
    }


    // 这个是开始的代码,由于这个网站 module 是存在的,所以 noGlobal 为 true,
    ( function( global, factory ) {

    "use strict";

    if ( typeof module === "object" && typeof module.exports === "object" ) {

    // For CommonJS and CommonJS-like environments where a proper `window`
    // is present, execute the factory and get jQuery.
    // For environments that do not have a `window` with a `document`
    // (such as Node.js), expose a factory as module.exports.
    // This accentuates the need for the creation of a real `window`.
    // e.g. var jQuery = require("jquery")(window);
    // See ticket #14549 for more info.
    module.exports = global.document ?
    factory( global, true ) :
    function( w ) {
    if ( !w.document ) {
    throw new Error( "jQuery requires a window with a document" );
    }
    return factory( w );
    };
    } else {
    factory( global );
    }

    // Pass this if window is not defined yet
    } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {...}
    shinpei
        16
    shinpei  
       2019-07-18 20:26:35 +08:00   1
    简单点就是你去修改下 jquery 源码,把 if (!noGlobal) 判断去掉
    hgjian
        17
    hgjian  
    OP
       2019-07-18 20:48:28 +08:00
    @shinpei 感谢
    hgjian
        18
    hgjian  
    OP
       2019-07-18 20:54:55 +08:00
    @shinpei 请问,去掉判断以后,那 jq 没有全局注册,怎么调用 jq 呢?
    hgjian
        19
    hgjian  
    OP
       2019-07-18 20:56:20 +08:00
    @shinpei 直接使用 jQuery ?
    hgjian
        20
    hgjian  
    OP
       2019-07-18 20:58:01 +08:00
    @shinpei 请问有没有不修改 jq 源码 的 方法呢?
    shinpei
        21
    shinpei  
       2019-07-18 21:03:17 +08:00
    @hgjian 我的意思是把
    if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
    }
    直接写成
    window.jQuery = window.$ = jQuery;
    hgjian
        22
    hgjian  
    OP
       2019-07-18 21:05:25 +08:00
    @shinpei 刚刚试过,好像不行
    hgjian
        23
    hgjian  
    OP
       2019-07-18 21:15:32 +08:00
    @shinpei 搞定了,
    await page.addScriptTag({
    path: './node_modules/jquery/dist/jquery.js',
    });
    应该放在 page.goto 的后面,就可以了

    谢谢啊
    shinpei
        24
    shinpei  
       2019-07-18 21:40:27 +08:00
    @hgjian 不客气
    123s
        25
    123s  
       2019-07-19 14:34:25 +08:00
    根本不需要 jq 吧
    xuyl
        26
    xuyl  
       2019-07-26 14:22:19 +08:00
    cheerio 就是服务端的 jQuery
    hgjian
        27
    hgjian  
    OP
       2019-07-26 23:32:09 +08:00 via Android
    @xuyl 了解了,谢谢啊
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2952 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 12:26 PVG 20:26 LAX 04:26 JFK 07:26
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86