将 jQuery 注入 Puppeteer 页面

Inject jQuery into Puppeteer page

我正在尝试将 jQuery 注入我的 Puppeteer 页面,因为 document.querySelector 不适合我:

async function inject_jquery(page){
  await page.evaluate(() => {
    var jq = document.createElement("script")
    jq.src = "https://code.jquery.com/jquery-3.2.1.min.js"
    document.querySelector("head").appendChild(jq)
  })
  const watchDog = page.waitForFunction('window.jQuery !== undefined');
  await watchDog;
}

结果大多是超时。有人有解决办法吗?

我已经使用 page.addScriptTag 注入了 js 个文件。

...
await page.addScriptTag({url: 'https://code.jquery.com/jquery-3.2.1.min.js'})
...

page.addScriptTag - 文档

使用puppeteer: 0.12.0

的工作示例
import { launch } from 'puppeteer'
(async () => {
    const browser = await launch({headless: false});
    const page = await browser.newPage();
    await page.goto('https://example.com', {waitUntil: 'networkidle'});
    await page.addScriptTag({url: 'https://code.jquery.com/jquery-3.2.1.min.js'});
    await page.close();
    await browser.close();
})();

这对我有用。

async function inject_jquery(page){
      await page.evaluate(() => {
        var jq = document.createElement("script")
        jq.setAttribute('type','text/javascript');
        jq.src = "https://code.jquery.com/jquery-3.2.1.min.js"
        return new Promise( (resolve) => {
            jq.addEventListener("load", ()=> {
                resolve();
            });
            document.getElementsByTagName("head")[0].appendChild(jq);
        });
      })
      const watchDog = page.waitForFunction('window.jQuery !== undefined');
      await watchDog;
    }

我正在这样做:

await page.addScriptTag({ url: 'https://code.jquery.com/jquery-3.2.1.min.js' });
const title = await page.evaluate(() => {
  const $ = window.$; //otherwise the transpiler will rename it and won't work
  return $('h1 > span').text();
});

对于那些希望注入 jQuery 的本地副本的人:

await page.addScriptTag({path: require.resolve('jquery')})

有些网站不允许您注入脚本标签,因此您必须先注入它的内容,然后它才会允许您这样做。如果是这种情况,您可以使用 evaluate 方法从 CDN 获取脚本内容并手动注入它们:

const jquery = await page.evaluate(() => window.fetch('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js').then((res) => res.text()));
await page.goto(YOUR_PAGE_HERE);
await page.evaluate(jquery);

如果你想在野外看到一个例子,这用于为 browserless here(我是这个工具的作者)抓取 puppeteer 的文档。

如果您有这样的

,如果您将脚本注入 html 页眉,管理起来会更容易
<script type="text/javascript" src="abc.min.js"></script>

现在您可以在 page.evaluate(function(){ })

中轻松调用它的函数

从 CDN 注入 jQuery(受上述@browserless 回答的启发):

// go to page
await page.goto(url_str);
        
// inject jQuery
var jquery_ev_fn = await page.evaluate(function(){
    return window.fetch('https://code.jquery.com/jquery-3.4.1.min.js').then(function(res){
        return res.text();
    });
});
await page.evaluate(jquery_ev_fn);

注入本地jQuery:

// get local jQuery and inject it
var jquery_code_str = fs.readFileSync('/path/to/local/jquery.js', 'utf8');

// go to page
await page.goto(url_str);
        
// inject jQuery
var jquery_ev_fn = await page.evaluate(function(code_str){
    return code_str;
}, jquery_code_str);
await page.evaluate(jquery_ev_fn);

我刚刚发布了我的人偶 jquery 集成 here

代码示例:

let browser = await launch({headless: true});
let pageOrg = await browser.newPage();
let page = pageExtand(pageOrg);
// append a <H1>
await page.jQuery('body').append(`<h1>Title</h1>`);
// get the H1 value
let title = await page.jQuery('h1').text();
// chain calls
let text = await page.jQuery('body button:last')
          .closest('div')
          .find('h3')
          .css('color', 'yellow')
          .parent()
          .find(':last')
          .text();

尚未映射所有 jQuery 函数,因此如果您需要更多函数,请打开问题(每个调用都需要按名称和它们采用的参数数量添加)。

您可以使用以下方法将jQuery添加到使用page.evaluate()的页面:

await page.evaluate(async () => {
  const script = document.createElement('script');
  script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js';
  const promise = new Promise((resolve, reject) => {
    script.onload = resolve;
    script.onerror = reject;
  });
  document.head.appendChild(script);
  await promise;
});

目前找到的最佳解决方案,URL插入可能由于浏览器源策略而无法工作,所以我们插入本地文件内容而不是URL .

const fs = require('fs');
const path = require('path');

const addJQueryToPage = async (page) => {
    const file = fs.readFileSync(path.resolve(__dirname, 'jquery-file-in-same-directory.min.js'), 'utf8');
    await page.addScriptTag({ content: file });
    await page.evaluate(_ => {
        $.noConflict();
    });
}