Kuklacı: .evaluate () içindeki değişkeni geçirin


128

Puppeteer'da bir değişkeni bir page.evaluate()işleve geçirmeye çalışıyorum , ancak aşağıdaki çok basitleştirilmiş örneği kullandığımda, değişken tanımsız.evalVar

Puppeteer'da yeniyim ve üzerine inşa edilecek herhangi bir örnek bulamıyorum, bu page.evaluate()yüzden içeride kullanabilmek için bu değişkeni işleve geçirmede yardıma ihtiyacım var.

const puppeteer = require('puppeteer');

(async() => {

  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const evalVar = 'WHUT??';

  try {

    await page.goto('https://www.google.com.au');
    await page.waitForSelector('#fbar');
    const links = await page.evaluate((evalVar) => {

      console.log('evalVar:', evalVar); // appears undefined

      const urls = [];
      hrefs = document.querySelectorAll('#fbar #fsl a');
      hrefs.forEach(function(el) {
        urls.push(el.href);
      });
      return urls;
    })
    console.log('links:', links);

  } catch (err) {

    console.log('ERR:', err.message);

  } finally {

    // browser.close();

  }

})();

Yanıtlar:


189

Değişkeni aşağıdaki gibi bir argüman olarak iletmelisiniz pageFunction:

const links = await page.evaluate((evalVar) => {

  console.log(evalVar); // 2. should be defined now
  

}, evalVar); // 1. pass variable as an argument

Argümanlar ayrıca serileştirilebilir: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args .


3
Merhaba, birden çok değişkeni nasıl iletirsiniz?
chitzui

4
Ayrıca, bir işlevi gerçekten iletemiyorum: var myFunction = function () {console.log ("merhaba")}; page.evaluate (func => func (), myFunction); bana verir: Evaluation failed: TypeError: func is not a function.. Neden?
chitzui

1
Tip unutma evalVarfonksiyonu argüman imza hem ve bir geçmiş argüman olarak evaluate(kod örneği sonunda).
Flimm

2
@chitzui: Bir işlevi devredemezsiniz pate.evaluate(). Sözde 'ifşa edebilirsiniz' page.exposeFunction. Daha fazla bilgi için stackoverflow.com/a/58040978 adresine bakın .
58'de knod

Bu en yüksek oy oranına sahip olduğundan, bununla ilgili herhangi bir hata ile karşılaşan oldu mu? özellikle üst kapsamda zaten tanımlanmış parametre ile. Bu hatanın yanı sıra, bu işe yarıyor.
Mix Master Mike

61

Bu stile bağlı kalmanızı tavsiye ederim çünkü daha rahat ve okunaklı .

let name = 'jack';
let age  = 33;
let location = 'Berlin/Germany';

await page.evaluate(({name, age, location}) => {

    console.log(name);
    console.log(age);
    console.log(location);

},{name, age, location});

41

Tek Değişken:

Sen geçebilir bir değişken için page.evaluate()aşağıdaki sözdizimini kullanarak:

await page.evaluate(example => { /* ... */ }, example);

Not:() Birden çok değişkeni aktarmayacaksanız değişkeni içine almanız gerekmez .

Çoklu Değişkenler:

Sen geçebilir birden çok değişkeni için page.evaluate()aşağıdaki sözdizimini kullanarak:

await page.evaluate((example_1, example_2) => { /* ... */ }, example_1, example_2);

Not: Değişkenlerinizi içine almak {}gerekli değildir.


12

O anlamaya bana oldukça zaman aldı console.log()içinde evaluate()düğüm konsolunda gösteremez.

Referans: https://github.com/GoogleChrome/puppeteer/issues/1944

page.evaluate işlevi içinde çalıştırılan her şey tarayıcı sayfası bağlamında yapılır. Komut dosyası node.js'de değil tarayıcıda çalışıyor, bu nedenle oturum açarsanız tarayıcı konsolunda görünecek ve başsız çalıştırıyorsanız göremeyeceksiniz. Ayrıca, işlevin içinde bir düğüm kesme noktası ayarlayamazsınız.

Umarım bu yardımcı olabilir.


6

Geçiş a functioniçin bunu yapmanın iki yolu vardır.

// 1. Defined in evaluationContext
await page.evaluate(() => {
  window.yourFunc = function() {...};
});
const links = await page.evaluate(() => {
  const func = window.yourFunc;
  func();
});


// 2. Transform function to serializable(string). (Function can not be serialized)
const yourFunc = function() {...};
const obj = {
  func: yourFunc.toString()
};
const otherObj = {
  foo: 'bar'
};
const links = await page.evaluate((obj, aObj) => {
   const funStr = obj.func;
   const func = new Function(`return ${funStr}.apply(null, arguments)`)
   func();

   const foo = aObj.foo; // bar, for object
   window.foo = foo;
   debugger;
}, obj, otherObj);

devtools: trueTest için başlatma seçeneklerine ekleyebilirsiniz


Ve bir nesneyi geçmek mi istedim?
tramada

2. durumda nasıl bir argüman eklersiniz? örneğin, sizinFunc
user3568719

yourFuncÖzelliğiniz bir işlev değilse nesne ile değiştirebilirsiniz . @tramada
wolf

func, size benzerFunc , böylece, tıpkı yourFunc @ user3568719'da olduğu gibi func (stringArg) 'ı çağırabilirsiniz
wolf

Bir nesneyi pencereye nasıl geçireceğinizi ve sonra ona nasıl erişeceğinizi gösterir misiniz?
wuno

2

Daktilo konusunda yeni birine yardımcı olabilecek bir typcript örneğim var.

const hyperlinks: string [] = await page.evaluate((url: string, regex: RegExp, querySelect: string) => {
.........
}, url, regex, querySelect);

puppeteerDaktilo ile nasıl çalışıyorsunuz ? Kodunuzu her değiştirdiğinizde js'ye aktarıyor musunuz?
avalanche 1

Evet. Bu projeye buradan bir göz atabilirsiniz - github.com/srinivasreddy/companies-list
Srinivas Reddy Thatiparthy

-1

İle sayfa. $$ eval

//..
const page = await browser.newPage();
const hrefs = await page.$$eval('#fbar #fsl a', as => as.map(a => a.href));
console.log(hrefs);
//..

[ayrıca . tek bir seçici için $ eval sayfasına bakın ]


Bu soruya nasıl cevap veriyor? Test bağlamından tarayıcı bağlamına geçirdiğiniz herhangi bir değişken görmüyorum.
Ambroise Rabier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.