I’m building a stock price scraper using Puppeteer and Node.js that searches Google for stock information. Users input a stock symbol which gets added to a Google search URL, then I extract the price change data.
The problem is inconsistent behavior - sometimes it works perfectly, other times I get this error: Error: Evaluation failed: TypeError: Cannot read property 'textContent' of null.
I tried using waitForSelector but it times out. Also attempted waitUntil: "domcontentloaded" with no success.
My code checks three different CSS selectors since Google shows different elements for positive, negative, or neutral price changes:
const browser = await puppeteer.launch({ args: ["--no-sandbox"] });
const pageInstance = await browser.newPage();
const stockSymbol = parseStock(userInput);
const searchUrl = "https://www.google.com/search?q=" + stockSymbol.symbol;
await pageInstance.goto(searchUrl, { waitUntil: "networkidle2"});
// Check for negative change first
var priceChange = await pageInstance.$(
"#knowledge-finance-wholepage__entity-summary > div > g-card-section > div > g-card-section > div.wGt0Bc > div:nth-child(1) > span.WlRRw.IsqQVc.fw-price-dn > span:nth-child(1)"
);
if (priceChange == null) {
// Check for positive change
priceChange = await pageInstance.$(
"#knowledge-finance-wholepage__entity-summary > div > g-card-section > div > g-card-section > div.wGt0Bc > div:nth-child(1) > span.WlRRw.IsqQVc.fw-price-up > span:nth-child(1)"
);
if (priceChange == null) {
// Check for no change
priceChange = await pageInstance.$(
"#knowledge-finance-wholepage__entity-summary > div > g-card-section > div > g-card-section > div.wGt0Bc > div:nth-child(1) > span.WlRRw.IsqQVc.fw-price-nc > span:nth-child(1)"
);
}}
const changeText = await pageInstance.evaluate(
(element) => element.textContent,
priceChange
);
How can I make this more reliable?