将jquery注入puppeteer页面

时间:2017-10-28 07:56:20

标签: jquery node.js puppeteer

我正在尝试将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;
}

结果是它大部分时间过去了。有没有人有解决方案?

10 个答案:

答案 0 :(得分:27)

我使用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();
})();

答案 1 :(得分:13)

对于那些想要注入jQuery的本地副本的人:

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

答案 2 :(得分:9)

我这样做:

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();
});

答案 3 :(得分:4)

这适合我。

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;
    }

答案 4 :(得分:1)

某些网站不允许您注入脚本标记,因此您必须先注入其内容,然后才允许您这样做。如果是这种情况,您可以使用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);

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

答案 5 :(得分:1)

我刚刚发布了伪造的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函数,因此,如果您需要更多函数(每个调用都需要通过名称以及使用的参数数量添加),则存在未解决的问题。

答案 6 :(得分:1)

迄今为止最好的解决方案,由于浏览器来源政策,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();
    });
}

答案 7 :(得分:0)

如果您将脚本插入到html页面标题中,则变得更容易管理

<script type="text/javascript" src="abc.min.js"></script>

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

中轻松调用其功能。

答案 8 :(得分:0)

要从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
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);

答案 9 :(得分:0)

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

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;
});