I am using Puppeteer in a Node.js module. I retrieve an HTML element with an XPath selector and need to extract the text property.
Currently I use:
// Get the element
let ele = await element.$x(`//div[@class="g"][${i}]/div/div/h3/a`);
// Get the text property
const title = await(await ele[0].getProperty('text')).jsonValue();
Is there any way to do this without being so verbose?
ElementHandle prevents DOM element from garbage collection unless the handle is disposed . ElementHandles are auto-disposed when their origin frame gets navigated. ElementHandle instances can be used as arguments in page.
Represents a reference to a JavaScript object. Instances can be created using Page. evaluateHandle(). Handles prevent the referenced JavaScript object from being garbage-collected unless the handle is purposely disposed.
$$eval() method. This method runs Array. from(document. querySelectorAll(selector)) within the page and passes the result as the first argument to the pageFunction .
Returns either null or the object handle itself, if the object handle is an instance of ElementHandle. This method returns the bounding box of the element (relative to the main frame), or null if the element is not visible. This method returns boxes of the element, or null if the element is not visible.
ElementHandle instances can be used as arguments in page.$eval and page.evaluate methods. Returns either null or the object handle itself, if the object handle is an instance of ElementHandle. This method returns the bounding box of the element (relative to the main frame), or null if the element is not visible.
ElementHandle instances can be used as arguments in page.$eval and page.evaluate methods. Returns either null or the object handle itself, if the object handle is an instance of ElementHandle.
ElementHandles are auto-disposed when their origin frame gets navigated. ElementHandle instances can be used as arguments in page.$eval and page.evaluate methods. Returns either null or the object handle itself, if the object handle is an instance of ElementHandle.
...or write a tiny helper function.
public async GetProperty(element: ElementHandle, property: string): Promise<string> {
return await (await element.getProperty(property)).jsonValue();
}
use:
let inner = await GetProperty(ele, 'innerHTML');
I would rather extend ElementHandle for missing methods like:
// [email protected]
let { ElementHandle } = require( "puppeteer/lib/ExecutionContext" );
// [email protected]
if ( ElementHandle === undefined ) {
ElementHandle = require( "puppeteer/lib/JSHandle" ).ElementHandle;
}
/**
* Set value on a select element
* @param {string} value
* @returns {Promise<Undefined>}
*/
ElementHandle.prototype.select = async function( value ) {
await this._page.evaluateHandle( ( el, value ) => {
const event = new Event( "change", { bubbles: true });
event.simulated = true;
el.querySelector( `option[value="${ value }"]` ).selected = true;
el.dispatchEvent( event );
}, this, value );
};
/**
* Check if element is visible in the DOM
* @returns {Promise<Boolean>}
**/
ElementHandle.prototype.isVisible = async function(){
return (await this.boundingBox() !== null);
};
/**
* Get element attribute
* @param {string} attr
* @returns {Promise<String>}
*/
ElementHandle.prototype.getAttr = async function( attr ){
const handle = await this._page.evaluateHandle( ( el, attr ) => el.getAttribute( attr ), this, attr );
return await handle.jsonValue();
};
/**
* Get element property
* @param {string} prop
* @returns {Promise<String>}
*/
ElementHandle.prototype.getProp = async function( prop ){
const handle = await this._page.evaluateHandle( ( el, prop ) => el[ prop ], this, prop );
return await handle.jsonValue();
};
As soon as you import this module once in you code you can play with the handles as follows:
const elh = await page.$( `#testTarget` );
console.log( await elh.isVisible() );
console.log( await elh.getAttr( "class" ) );
console.log( await elh.getProp( "innerHTML" ) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With