Comments
pcraig3
added a commit
to cds-snc/ircc-rescheduler
that referenced
this issue
Sep 7, 2018
This function will call `page.click` and then `page.waitFor`. Running this several times locally, it's gotten rid of the `execution context was destroyed` error. Seems like the error is occurring because the page is being navigated in a way that puppeteer doesn't like. - puppeteer/puppeteer#1591 (comment) Someone suggested using page.waitFor and that solved their issue Seems to work for our case. - puppeteer/puppeteer#1591 (comment)
pcraig3
added a commit
to cds-snc/ircc-rescheduler
that referenced
this issue
Sep 7, 2018
This function will call `page.click` and then `page.waitFor`. Running this several times locally, it's gotten rid of the `execution context was destroyed` error. Seems like the error is occurring because the page is being navigated in a way that puppeteer doesn't like. - puppeteer/puppeteer#1591 (comment) Someone suggested using page.waitFor and that solved their issue Seems to work for our case. - puppeteer/puppeteer#1591 (comment)
pcraig3
added a commit
to cds-snc/ircc-rescheduler
that referenced
this issue
Sep 7, 2018
We were seeing a lot of intermittent failures when running `yarn test:full` with the puppeteer tests giving us an `Execution context was destroyed` error. Seems like that error message is trying to tell us that the page is being navigated away from in a way that puppeteer doesn't like. - puppeteer/puppeteer#1591 (comment) Someone suggested using page.waitFor because that solved their issue. Seems to work for our case. - puppeteer/puppeteer#1591 (comment) Created a new function `clickAndWait` that will call page.click and then page.waitFor. Running this a bunch of times locally and our tests seems to pass reliably now.
nmakuch
pushed a commit
to cds-snc/ircc-rescheduler
that referenced
this issue
Sep 11, 2018
We were seeing a lot of intermittent failures when running `yarn test:full` with the puppeteer tests giving us an `Execution context was destroyed` error. Seems like that error message is trying to tell us that the page is being navigated away from in a way that puppeteer doesn't like. - puppeteer/puppeteer#1591 (comment) Someone suggested using page.waitFor because that solved their issue. Seems to work for our case. - puppeteer/puppeteer#1591 (comment) Created a new function `clickAndWait` that will call page.click and then page.waitFor. Running this a bunch of times locally and our tests seems to pass reliably now.
I am trying to use node/puppeteer to retrieve items from an unordered list. I am able to navigate to the page, perform a search, but when I attempt to generate an array with the lis, it breaks with the following error:
UnhandledPromiseRejectionWarning: Error: Protocol error
(Runtime.callFunctionOn): Execution context was destroyed.
Responding to the comment, here is the full code:
require('dotenv').config();
const puppeteer = require('puppeteer');
const ac = require("@antiadmin/anticaptchaofficial");
(async () => {
ac.setAPIKey(process.env.ANTICAPTCHA_KEY);
ac.getBalance()
.then(balance => console.log('my balance is $'+balance))
.catch(error => console.log('received error '+error))
console.log('solve recaptcha first');
let token = await ac.solveRecaptchaV2Proxyless('https://secure.meetup.com/login','6LcA8EUUAAAAAG17qfEfNaX6H8ozmI-IvmokZUnZ');
if (!token) {
console.log('something went wrong with captcha solving');
return;
} else {
console.log('token is: ', token);
}
console.log ('opening browser');
const browser = await puppeteer.launch({
headless: false
});
console.log('creating new tab');
const page = await browser.newPage();
console.log('setting page size');
await page.setViewport({width: 1368, height: 1080})
console.log('opening target page');
await page.goto('https://secure.thesite.com/login', {waitUntil: 'networkidle2'});
await page.type('#email', process.env.MY_EMAIL)
await page.type('#password', process.env.MY_PASSWORD)
console.log('click login button');
await page.evaluate((token) => {
const textarea = document.querySelector("textarea#g-recaptcha-response.g-recaptcha-response")
if (textarea) {
textarea.innerText=token
}
const button = document.querySelector("#loginFormSubmit")
button.disabled = false
button.click()
}, token)
console.log('Entering keywords');
await page.waitForSelector("input#mainKeywords.dropdown-toggle.ellipsize")
await page.type("input#mainKeywords.dropdown-toggle.ellipsize","write")
console.log('Click to search and filter fr groups')
await page.evaluate(async () => {
const searchForm = document.querySelector("#searchForm")
searchForm.submit()
const groupButton = document.querySelector("#simple-view-selector-group")
await groupButton.click()
function sleep(seconds) {
return new Promise((resolve) => {
setTimeout(() => resolve(true), seconds*1000)
});
}
await sleep(2);
})
console.log('start grroups check')
const groups = page.evaluate(async () => {
console.log('setting grroups aray');
const groups=[];
console.log('about to awaait selector');
if (await page.waitForSelector('a.groupCard--photo.loading.nametag-photo') !== null) {
const groupList = document.querySelectorAll("a.groupCard--photo.loading.nametag-photo")
console.log("groupis is: ", groupList);
groupList.forEach(group => {
groups.push(group.href);
})
return groups;
} else {
console.log('selector is null');
}
})
console.log(groups);
})();
Are you using the latest version of the library?
- I have checked and am using the latest version of the library.
What type of session are you experiencing this issue on?
Multi-device and I have set multiDevice to true in my config OR am using the —multi-device flag
What type of host account are you experiencing this issue on?
Business account
Mode
My own code
Current Behavior
After starting my Code, the Bot seems to «disconnect» after ~5 mins and reconnects instantly
[Client State] - T0G3_PRIV_BS - OPENING [Client State] - T0G3_PRIV_BS - PAIRING [Client State] - T0G3_PRIV_BS - CONNECTED
then there occures a puppeteer crash.
[ERROR] ProtocolError: Protocol error (Runtime.callFunctionOn): Execution context was destroyed. at C:UsersAdminDesktopBotsMainnode_modulespuppeteerlibcjspuppeteercommonConnection.js:230:24 at new Promise (<anonymous>) at CDPSession.send (C:UsersAdminDesktopBotsMainnode_modulespuppeteerlibcjspuppeteercommonConnection.js:226:16) at ExecutionContext._evaluateInternal (C:UsersAdminDesktopBotsMainnode_modulespuppeteerlibcjspuppeteercommonExecutionContext.js:204:50) at ExecutionContext.evaluate (C:UsersAdminDesktopBotsMainnode_modulespuppeteerlibcjspuppeteercommonExecutionContext.js:110:27) at DOMWorld.evaluate (C:UsersAdminDesktopBotsMainnode_modulespuppeteerlibcjspuppeteercommonDOMWorld.js:97:24) at runMicrotasks (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:97:5) { originalMessage: 'Execution context was destroyed.' }
Expected Behavior
no crash lul. <3
Steps To Reproduce
Win10 — 64 Bit
Node 12.22.1
wa-automate-nodejs 4.32.17
wa_version: 2.2208.14
browser_version: HeadlessChrome/99.0.4844.82
page_ua: WhatsApp/2.2147.16 Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
create() code
var _t0g3_priv_lic = "REMOVED_FOR_GITHUB"; var md = true const hosts = ["T0G3_PRIV_BS"]; for (var i = 0; i < hosts.length; i++) { if (hosts[i] != 'T0G3_PRIV_BS') { _t0g3_priv_lic = undefined; md = false } create({ "licenseKey": _t0g3_priv_lic, "headless": true, "cacheEnabled": true, "useChrome": true, "restartOnCrash": startServer, "qrTimeout": 0, "authTimeout": 120, "sessionId": hosts[i], "sesseionDataPath": '../Sessions', "multiDevice": md, "cachedPatch": true, "skipBrokenMethodsCheck": true, "blockAssets": true, "skipUpdateCheck": true, "disableSpins": false, "discord": "907573119433187329" }) .then(async (client) => startServer(client)) .catch((error) => console.log(error)) }
DEBUG INFO
{ "WA_VERSION": "2.2208.14", "WA_AUTOMATE_VERSION": "4.32.17", "BROWSER_VERSION": "HeadlessChrome/99.0.4844.82", "START_TS": 1648395831273, "LATEST_VERSION": true, "CLI": false }
Environment
- OS: Windows 10 - Node: 12.22.1 - npm: 7.20.5
Screenshots/Logs
No response
Anything else?
Ping me on Discord if you need further Information ƬӨGΣPII#1337
Methods
Runtime.awaitPromise
#
Add handler to promise with given promise object id.
parameters
- promiseObjectId
-
RemoteObjectId
Identifier of the promise.
- returnByValue
-
boolean
Whether the result is expected to be a JSON object that should be sent by value.
- generatePreview
-
boolean
Whether preview should be generated for the result.
Return Object
- result
-
RemoteObject
Promise result. Will contain rejected value if promise was rejected.
- exceptionDetails
-
ExceptionDetails
Exception details if stack strace is available.
Runtime.callFunctionOn
#
Calls function with given declaration on the given object. Object group of the result is inherited from the target object.
parameters
- objectId
-
RemoteObjectId
Identifier of the object to call function on.
- functionDeclaration
-
string
Declaration of the function to call.
- arguments
-
array[ CallArgument ]
Call arguments. All call arguments must belong to the same JavaScript world as the target object.
- silent
-
boolean
In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides
setPauseOnException
state. - returnByValue
-
boolean
Whether the result is expected to be a JSON object which should be sent by value.
- generatePreview
-
boolean
Whether preview should be generated for the result.
Experimental
- userGesture
-
boolean
Whether execution should be treated as initiated by user in the UI.
Experimental
- awaitPromise
-
boolean
Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it’s considered to be an error.
Return Object
- result
-
RemoteObject
Call result.
- exceptionDetails
-
ExceptionDetails
Exception details.
Runtime.compileScript
#
Compiles expression.
parameters
- expression
-
string
Expression to compile.
- sourceURL
-
string
Source url to be set for the script.
- persistScript
-
boolean
Specifies whether the compiled script should be persisted.
- executionContextId
-
ExecutionContextId
Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page.
Return Object
- scriptId
-
ScriptId
Id of the script.
- exceptionDetails
-
ExceptionDetails
Exception details.
Runtime.disable
#
Disables reporting of execution contexts creation.
Runtime.discardConsoleEntries
#
Discards collected exceptions and console API calls.
Runtime.enable
#
Enables reporting of execution contexts creation by means of executionContextCreated
event. When the reporting gets enabled the event will be sent immediately for each existing execution context.
Runtime.evaluate
#
Evaluates expression on global object.
parameters
- expression
-
string
Expression to evaluate.
- objectGroup
-
string
Symbolic group name that can be used to release multiple objects.
- includeCommandLineAPI
-
boolean
Determines whether Command Line API should be available during the evaluation.
- silent
-
boolean
In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides
setPauseOnException
state. - contextId
-
ExecutionContextId
Specifies in which execution context to perform evaluation. If the parameter is omitted the evaluation will be performed in the context of the inspected page.
- returnByValue
-
boolean
Whether the result is expected to be a JSON object that should be sent by value.
- generatePreview
-
boolean
Whether preview should be generated for the result.
Experimental
- userGesture
-
boolean
Whether execution should be treated as initiated by user in the UI.
Experimental
- awaitPromise
-
boolean
Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it’s considered to be an error.
Return Object
- result
-
RemoteObject
Evaluation result.
- exceptionDetails
-
ExceptionDetails
Exception details.
Runtime.getProperties
#
Returns properties of a given object. Object group of the result is inherited from the target object.
parameters
- objectId
-
RemoteObjectId
Identifier of the object to return properties for.
- ownProperties
-
boolean
If true, returns properties belonging only to the element itself, not to its prototype chain.
- accessorPropertiesOnly
-
boolean
If true, returns accessor properties (with getter/setter) only; internal properties are not returned either.
Experimental
- generatePreview
-
boolean
Whether preview should be generated for the results.
Experimental
Return Object
- result
-
array[ PropertyDescriptor ]
Object properties.
- internalProperties
-
array[ InternalPropertyDescriptor ]
Internal object properties (only of the element itself).
- exceptionDetails
-
ExceptionDetails
Exception details.
Runtime.releaseObject
#
Releases remote object with given id.
parameters
- objectId
-
RemoteObjectId
Identifier of the object to release.
Runtime.releaseObjectGroup
#
Releases all remote objects that belong to a given group.
parameters
- objectGroup
-
string
Symbolic object group name.
Runtime.runIfWaitingForDebugger
#
Tells inspected instance to run if it was waiting for debugger to attach.
Runtime.runScript
#
Runs script with given id in a given context.
parameters
- scriptId
-
ScriptId
Id of the script to run.
- executionContextId
-
ExecutionContextId
Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page.
- objectGroup
-
string
Symbolic group name that can be used to release multiple objects.
- silent
-
boolean
In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides
setPauseOnException
state. - includeCommandLineAPI
-
boolean
Determines whether Command Line API should be available during the evaluation.
- returnByValue
-
boolean
Whether the result is expected to be a JSON object which should be sent by value.
- generatePreview
-
boolean
Whether preview should be generated for the result.
- awaitPromise
-
boolean
Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it’s considered to be an error.
Return Object
- result
-
RemoteObject
Run result.
- exceptionDetails
-
ExceptionDetails
Exception details.
Events
Runtime.consoleAPICalled
#
Issued when console API was called.
parameters
- type
-
string
Type of the call.
Allowed Values:
log
,debug
,info
,error
,warning
,dir
,dirxml
,table
,trace
,clear
,startGroup
,startGroupCollapsed
,endGroup
,assert
,profile
,profileEnd
- args
-
array[ RemoteObject ]
Call arguments.
- executionContextId
-
ExecutionContextId
Identifier of the context where the call was made.
- timestamp
-
Timestamp
Call timestamp.
- stackTrace
-
StackTrace
Stack trace captured when the call was made.
Runtime.exceptionRevoked
#
Issued when unhandled exception was revoked.
parameters
- reason
-
string
Reason describing why exception was revoked.
- exceptionId
-
integer
The id of revoked exception, as reported in
exceptionUnhandled
.
Runtime.exceptionThrown
#
Issued when exception was thrown and unhandled.
parameters
- timestamp
-
Timestamp
Timestamp of the exception.
- exceptionDetails
- ExceptionDetails
Runtime.executionContextCreated
#
Issued when new execution context is created.
parameters
- context
-
ExecutionContextDescription
A newly created execution contex.
Runtime.executionContextDestroyed
#
Issued when execution context is destroyed.
parameters
- executionContextId
-
ExecutionContextId
Id of the destroyed context
Runtime.executionContextsCleared
#
Issued when all executionContexts were cleared in browser
Runtime.inspectRequested
#
Issued when object should be inspected (for example, as a result of inspect() command line API call).
parameters
- object
- RemoteObject
- hints
- object
Types
Runtime.CallArgument
#
Represents function call argument. Either remote object id objectId
, primitive value
, unserializable primitive value or neither of (for undefined) them should be specified.
Type: object
properties
- value
-
any
Primitive value.
- unserializableValue
-
UnserializableValue
Primitive value which can not be JSON-stringified.
- objectId
-
RemoteObjectId
Remote object handle.
Runtime.CallFrame
#
Stack entry for runtime errors and assertions.
Type: object
properties
- functionName
-
string
JavaScript function name.
- scriptId
-
ScriptId
JavaScript script id.
- url
-
string
JavaScript script name or url.
- lineNumber
-
integer
JavaScript script line number (0-based).
- columnNumber
-
integer
JavaScript script column number (0-based).
Runtime.ExceptionDetails
#
Detailed information about exception (or error) that was thrown during script compilation or execution.
Type: object
properties
- exceptionId
-
integer
Exception id.
- text
-
string
Exception text, which should be used together with exception object when available.
- lineNumber
-
integer
Line number of the exception location (0-based).
- columnNumber
-
integer
Column number of the exception location (0-based).
- scriptId
-
ScriptId
Script ID of the exception location.
- url
-
string
URL of the exception location, to be used when the script was not reported.
- stackTrace
-
StackTrace
JavaScript stack trace if available.
- exception
-
RemoteObject
Exception object if available.
- executionContextId
-
ExecutionContextId
Identifier of the context where exception happened.
Runtime.ExecutionContextDescription
#
Description of an isolated world.
Type: object
properties
- id
-
ExecutionContextId
Unique id of the execution context. It can be used to specify in which execution context script evaluation should be performed.
- origin
-
string
Execution context origin.
- name
-
string
Human readable name describing given context.
- auxData
-
object
Embedder-specific auxiliary data.
Runtime.ExecutionContextId
#
Id of an execution context.
Type: integer
Runtime.InternalPropertyDescriptor
#
Object internal property descriptor. This property isn’t normally visible in JavaScript code.
Type: object
properties
- name
-
string
Conventional property name.
- value
-
RemoteObject
The value associated with the property.
Runtime.PropertyDescriptor
#
Object property descriptor.
Type: object
properties
- name
-
string
Property name or symbol description.
- value
-
RemoteObject
The value associated with the property.
- writable
-
boolean
True if the value associated with the property may be changed (data descriptors only).
- get
-
RemoteObject
A function which serves as a getter for the property, or
undefined
if there is no getter (accessor descriptors only). - set
-
RemoteObject
A function which serves as a setter for the property, or
undefined
if there is no setter (accessor descriptors only). - configurable
-
boolean
True if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object.
- enumerable
-
boolean
True if this property shows up during enumeration of the properties on the corresponding object.
- wasThrown
-
boolean
True if the result was thrown during the evaluation.
- isOwn
-
boolean
True if the property is owned for the object.
- symbol
-
RemoteObject
Property symbol object, if the property is of the
symbol
type.
Runtime.RemoteObject
#
Mirror object referencing original JavaScript object.
Type: object
properties
- type
-
string
Object type.
Allowed Values:
object
,function
,undefined
,string
,number
,boolean
,symbol
- subtype
-
string
Object subtype hint. Specified for
object
type values only.Allowed Values:
array
,null
,node
,regexp
,date
,map
,set
,iterator
,generator
,error
,proxy
,promise
,typedarray
- className
-
string
Object class (constructor) name. Specified for
object
type values only. - value
-
any
Remote object value in case of primitive values or JSON values (if it was requested).
- unserializableValue
-
UnserializableValue
Primitive value which can not be JSON-stringified does not have
value
, but gets this property. - description
-
string
String representation of the object.
- objectId
-
RemoteObjectId
Unique object identifier (for non-primitive values).
- preview
-
ObjectPreview
Preview containing abbreviated property values. Specified for
object
type values only.Experimental
- customPreview
-
CustomPreview
Experimental
Runtime.RemoteObjectId
#
Unique object identifier.
Type: string
Runtime.ScriptId
#
Unique script identifier.
Type: string
Runtime.StackTrace
#
Call frames for assertions or error messages.
Type: object
properties
- description
-
string
String label of this stack trace. For async traces this may be a name of the function that initiated the async call.
- callFrames
-
array[ CallFrame ]
JavaScript function name.
- parent
-
StackTrace
Asynchronous JavaScript stack trace that preceded this stack, if available.
Runtime.Timestamp
#
Number of milliseconds since epoch.
Type: number
Runtime.UnserializableValue
#
Primitive value which cannot be JSON-stringified.
Allowed Values: Infinity
, NaN
, -Infinity
, -0
Type: string
Answer by Beatrice Green
The error means that you are accessing data which has become obsolete/invalid because of navigation. In your script the error references the variable listeCompanies:,
What are the causes of negative real interest rates?
,Please be sure to answer the question. Provide details and share your research!,I recommend to go with option 1 as this also reduced the number of necessary navigation requests and will therefore speed up your script.
The error means that you are accessing data which has become obsolete/invalid because of navigation. In your script the error references the variable listeCompanies
:
const listeCompanies = await page.$$('.list-firms > div.firm');
This is the cleanest way to do it. You extract the information in the first page at once and then iterate over your extracted data. The nameLinkList
will be an array with the name
and link
values (e.g. [{name: '..', link: '..'}, {name: '..', link: '..'}]
). There is also no need to call page.goBack
at the end of the loop as the data is already extracted.
const nameLinkList = await page.$$eval(
'.list-firms > div.firm',
(firms => firms.map(firm => {
const a = firm.querySelector('.listing-body > h3 > a');
return {
name: a.innerText,
link: a.href
};
}))
);
for (const {name, link} of arr) {
await Promise.all([
page.waitForNavigation(),
page.goto(link),
page.waitForSelector('.firm-panel'),
]);
const info = await page.$eval('#info', e => e.innerText);
const data = [{
name: name,
information: info,
}];
}
In this case your browser will have two open pages. The first one will only be used to read the data, the second one is used for navigation.
const page2 = await browser.newPage();
for (const companie of listeCompanies ){
const name = await companie.$eval('.listing-body > h3 > a', name => name.innerText);
const link = await companie.$eval('.listing-body > h3 > a', link => link.href);
await Promise.all([
page2.goto(link),
page2.waitForSelector('.firm-panel'),
]);
const info = await page2.$eval('#info', e => e.innerText);
// ...
}
Here you simply re-execute your selector after going back to your «main page». Note, that the for..of
has to be change to an iterator-loop as we are replacing the array.
let listeCompanies = await page.$$('.list-firms > div.firm');
for (let i = 0; i < listeCompanies.length; i++){
// ...
await page.goBack();
listeCompanies = await page.$$('.list-firms > div.firm');
}
Answer by Celine Manning
Platform / OS version: Ubuntu 16.04,I’ve just hit the same problem.,Yes, it resolved the problem, thanks!,Puppeteer version: 1.8.0
const returnSearchResults = async (page) => {
const pageSource = await page.content();
if (/An error happened/.test(pageSource)) {
return 'fail';
}
else if (/queries have been found/.test(pageSource)) {
return 'success';
}
else if (/Timed out/.test(pageSource)) {
return 'timeout';
}
else if (/Your searches are too fast/.test(pageSource)) {
return 'too_fast';
}
else {
return await returnSearchResults(page);
}
}
const searchStep = async (page) => {
await page.type('#searchbox input', 'Testing');
await page.click('button[name="search"]');
let searchResults = await returnSearchResults(page);
if(searchResults === 'success') {
console.log('success finding results');
} else {
console.log(searchResults);
}
}
(async() => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
const page = await browser.newPage();
await page.goto('http://snippet.example.com/', {waitUntil: 'domcontentloaded'});
await searchStep(page).catch(e => {
console.log('step searchStep exception ' + e);
process.exit(1);
});
await page.close();
await browser.close();
})();
Answer by Shay Ibarra
The error means that you are accessing data which has become obsolete/invalid because of navigation. In your script the error references the variable listeCompanies:,I recommend to go with option 1 as this also reduced the number of necessary navigation requests and will therefore speed up your script.,Use a second pageto do the «loop navigation» so that your main page does not need to navigate,In this case your browser will have two open pages. The first one will only be used to read the data, the second one is used for navigation.
I am facing this problem in puppeteer in a for loop when i go on another page to get data, then when i go back it comes me this error line:
Error "We have an error Error: the execution context was destroyed, probably because of a navigation."
It’s a directory page that contains 15 companies per page and then I want to visit each company to get information.
try {
const browser = await pupputer.launch({
headless: false,
devtools: true,
defaultViewport: {
width: 1100,
height: 1000
}
});
const page = await browser.newPage();
await page.goto('MyLink');
await page.waitForSelector('.list-firms');
for (var i = 1; i < 10; i++) {
const listeCompanies = await page.$$('.list-firms > div.firm');
for (const companie of listeCompanies) {
const name = await companie.$eval('.listing-body > h3 > a', name => name.innerText);
const link = await companie.$eval('.listing-body > h3 > a', link => link.href);
await Promise.all([
page.waitForNavigation(),
page.goto(link),
page.waitForSelector('.firm-panel'),
]);
const info = await page.$eval('#info', e => e.innerText);
const data = [{
name: name,
information: info,
}];
await page.goBack();
}
await Promise.all([
page.waitForNavigation(),
page.click('span.page > a[rel="next"]')
]);
}
} catch (e) {
console.log('We have error', e);
}
Answer by Zahra Salgado
Execution context was destroyed, most likely because of a navigation.
create() code
wa.create({authTimeout: 0}).then(...)
DEBUG INFO
{
"WA_VERSION": "2.2136.9",
"WA_AUTOMATE_VERSION": "4.21.0",
"BROWSER_VERSION": "HeadlessChrome/87.0.4272.0",
"START_TS": 1631692321769
}
Environment
- OS: Linux 5.4
- Node: 12.21.0
- npm:
Answer by Marceline Stuart
Puppeteer version: 10.1.0,What happens instead?,What is the expected result?,Currently, everything is working as intended without my const scrapable = await page.evaluate(scrapablePageData); variable.
const dayjs = require('dayjs');
const AdvancedFormat = require('dayjs/plugin/advancedFormat');
dayjs.extend(AdvancedFormat);
const puppeteer = require('puppeteer');
const { config } = require('./config');
const helpers = require('./helpers');
const logs = require('./logs');
const runEmulation = async (body) => {
logs.debug('starting emulation');
// vars
const argOptions = [], journey = [];
// sandbox config
if ((config.puppeteer.run_in_sandbox === 'true')) {
argOptions.push('--no-sandbox');
}
// initiate a Puppeteer instance with options and launch
const browser = await puppeteer.launch({
args: argOptions,
headless: (config.puppeteer.run_in_headless === 'true') ? true : false
});
// launch a new page
const page = await browser.newPage()
// initiate a new CDP session
const client = await page.target().createCDPSession();
await client.send('Network.enable');
await client.on('Network.requestWillBeSent', async (e) => {
// if not a document, skip
if (e.type !== "Document") return;
// create a function to inject into the page to scrape data
const scrapablePageData = async () => {
/*
** Read localStorage
*/
function getLocalStorage () {
const values = [];
const keys = Object.keys(localStorage);
let index = keys.length;
while (index--) {
values.push({
key: keys[index],
value: localStorage.getItem(keys[index])
});
}
return values ? values : [];
}
return {
localStorage: getLocalStorage()
}
}
const scrapable = await page.evaluate(scrapablePageData);
const cookies = await page.cookies();
journey.push({
url: e.documentURL,
type: e.redirectResponse ? e.redirectResponse.status : 'JS Redirection',
storage: {
cookies: cookies ?? [],
local: scrapable.localStorage
},
duration_in_ms: 0,
duration_in_sec: 0,
loaded_at: dayjs().valueOf()
})
})
// set userAgent and go to the URL
await page.setUserAgent(body.userAgent);
await page.goto(body.url);
await page.waitForNavigation();
console.log(journey)
}
exports.runEmulation = runEmulation
Answer by Lia Hernandez
puppeteerでpage.clickを実行して画面遷移後にpage.evalute等を実行するとUnhandledPromiseRejectionWarning: Error: Execution context was destroyed, most likely because of a navigation.のような例外が起こる場合がある。,you can read useful information later efficientlyBy «stocking» the articles you like, you can search right away,We will deliver articles that match youBy following users and tags, you can catch up information on technical fields that you are interested in as a whole
await Promise.all([
page.waitForNavigation({waitUntil: ['load', 'networkidle2']}),
page.click('a.user-name')
]);
Answer by Scarlette Peters
Unofficial Python port of puppeteer JavaScript (headless) chrome/chromium browser automation library.,Pyppeteer is to be as similar as puppeteer, but some differences between python and JavaScript make it difficult.,Not intend to add original API which puppeteer does not have,After annotation — enable automation, the browser can’t detect the principle of automation tool
Install by pip from PyPI:
python3 -m pip install pyppeteer
Or install latest version from github:
python3 -m pip install -U git+https://github.com/miyakogi/[email protected]
import asyncio
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto('http://example.com')
await page.screenshot({'path': 'example.png'})
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
import asyncio
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto('http://example.com')
await page.screenshot({'path': 'example.png'})
dimensions = await page.evaluate('''() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
}
}''')
print(dimensions)
# >>> {'width': 800, 'height': 600, 'deviceScaleFactor': 1}
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
browser = await launch({'headless': True})
browser = await launch(headless=True)
content = await page.evaluate('document.body.textContent', force_expr=True)
element = await page.querySelector('h1')
title = await page.evaluate('(element) => element.textContent', element)