कठपुतली:। चर मूल्यांकन में चर ()


128

मैं Puppeteer में एक page.evaluate()फंक्शन में एक वैरिएबल को पास करने की कोशिश कर रहा हूं , लेकिन जब मैं निम्नलिखित बहुत सरलीकृत उदाहरण का उपयोग करता हूं, तो वैरिएबल अपरिभाषित है।evalVar

मैं कठपुतली के लिए नया हूँ और निर्माण करने के लिए कोई उदाहरण नहीं खोज सकता, इसलिए मुझे उस चर को page.evaluate()फ़ंक्शन में पास करने में मदद चाहिए ताकि मैं इसे अंदर उपयोग कर सकूं।

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

  }

})();

जवाबों:


188

आपको चर को इस pageFunctionतरह एक तर्क के रूप में पारित करना होगा:

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

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

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

तर्कों को क्रमबद्ध भी किया जा सकता है: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageev मूल्यांकनpagefunction- args


3
हैलो, आप कई चर कैसे पारित करेंगे?
चिट्ज़ुई

4
इसके अलावा, मैं वास्तव में एक फ़ंक्शन पास करने में सक्षम नहीं हूं: var myFunction = function () {कंसोल.लॉग ("हैलो")}; प्रतीक्षित पृष्ठ। मूल्यांकन (func => func (), myFunction); मुझे देता है: Evaluation failed: TypeError: func is not a function.. क्यों?
चिट्ज़ुई

1
evalVarफ़ंक्शन तर्क हस्ताक्षर, और पास किए गए तर्क के रूप में evaluate(कोड उदाहरण के अंत में) दोनों को टाइप करना न भूलें ।
फ़्लिम

2
@chitzui: आप किसी फ़ंक्शन को पास नहीं कर सकते pate.evaluate()। आप इसे कथित रूप से 'एक्सपोज़' कर सकते हैं page.exposeFunction। अधिक जानकारी के लिए, stackoverflow.com/a/58040978 देखें ।
२।

चूँकि इसमें सबसे अधिक उत्थान होता है, क्या किसी को इसके साथ लाइनिंग में कोई त्रुटि हुई है? विशेष रूप से पहले से ही ऊपरी दायरे में घोषित पैरामीटर के साथ। इस त्रुटि से अलग, यह काम करता है।
मास्टर माइक

61

मैं आपको इस शैली पर टिकने के लिए प्रोत्साहित करता हूं, क्योंकि यह अधिक सुविधाजनक और पठनीय है

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

40

एकल चर:

आप पास कर सकते हैं एक चर करने के लिए page.evaluate()निम्न सिंटैक्स का उपयोग कर:

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

नोट: आपको वैरिएबल को घेरने की जरूरत नहीं है (), जब तक कि आप कई वैरिएबल पास नहीं करेंगे।

एकाधिक चर:

आप पास कर सकते हैं कई चर करने के लिए page.evaluate()निम्न सिंटैक्स का उपयोग कर:

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

नोट: अपने चरों को अंदर लाना {}आवश्यक नहीं है।


12

यह मुझे काफी समय लगा यह पता लगाने की है कि console.log()में evaluate()नोड कंसोल में नहीं दिखा सकते हैं।

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

सब कुछ जो page.ev मूल्यांकन फ़ंक्शन के अंदर चलाया जाता है, ब्राउज़र पेज के संदर्भ में किया जाता है। स्क्रिप्ट नोड में नहीं ब्राउज़र में चल रही है। इसलिए यदि आप लॉग करते हैं तो यह ब्राउज़र कंसोल में दिखाई देगा जो यदि आप बिना सिर के चल रहे हैं तो आप नहीं देखेंगे। आप फ़ंक्शन के अंदर नोड ब्रेकपॉइंट भी सेट नहीं कर सकते।

आशा है कि यह मदद कर सकता है।


6

पास होने के लिए function, दो तरीके हैं जो आप कर सकते हैं।

// 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: trueपरीक्षण के लिए लॉन्च विकल्पों में जोड़ सकते हैं


और मैं एक वस्तु पारित करना चाहता था?
त्रिमदा

आप 2 के मामले में एक तर्क कैसे जोड़ेंगे? उदाहरण के लिए मैं अपने स्ट्रिंग को पास करना चाहता हूं
16:35 पर user3568719

आप yourFuncऑब्जेक्ट से बदल सकते हैं यदि आपकी संपत्ति एक फ़ंक्शन नहीं है। @tramada
भेड़िया

func आपके जैसा है ununc is ताकि आप func (stringArg) को कॉल कर सकें, जैसे अपनेFunc @ user3568719 को निष्पादित करें
wolf

क्या आप यह दर्शाते हैं कि आप किसी ऑब्जेक्ट को विंडो में कैसे पास करेंगे और फिर उसे एक्सेस करेंगे?
वूनो

2

मेरे पास एक टाइपस्क्रिप्ट उदाहरण है जो टाइपस्क्रिप्ट में किसी नए की मदद कर सकता है।

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

आप puppeteerटाइपस्क्रिप्ट में कैसे चलते हैं ? क्या आप अपने कोड को संशोधित करने के लिए हर बार जेएस को ट्रांसपाइल करते हैं?
हिमस्खलन 1

हाँ। आप यहाँ इस परियोजना पर एक नज़र ले जा सकते हैं - github.com/srinivasreddy/companies-list
श्रीनिवास रेड्डी Thatiparthy

-1

पेज के साथ । $$ eval

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

[ पेज पर भी देखें एकल चयनकर्ता के लिए $ eval ]


कैसे इस सवाल का जवाब देता है? मुझे ऐसा कोई चर नहीं दिख रहा है जिसे आप परीक्षण के संदर्भ से ब्राउज़र संदर्भ में पास कर रहे हैं।
राबियर जूल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.