npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

undetected-browser

v2.0.1

Published

Puppeteer implementation with more anti-detection methods for interacting with websites

Downloads

538

Readme

Undetected Browser

Undetected Browser is a framework that extends Puppeteer capabilities with even more usefull functions. It can run any puppeteer browser instance and its modular system will allow you to build plugins on top of it. Special thanks to @TheGP and @wiz64 for support on codebase ideeas.

Features

  • Works with Bablosoft, Puppeteer, Puppeteer Stealth
  • Implement more complicated functions for better selectors, better navigation waiting etc.
  • Mimic human like interaction on the page through special functions
  • Uses @forad/puppeteer-humanize and ghost-cursor to deliver results

Installation

  npm install undetected-browser

or for bun users

  bun install undetected-browser

Usage/Examples

NOTE: You can use any driver powered by puppeteer like pupeteer-extra or puppeteer-with-fingerprints (bablosoft)

const UndetectableBrowser = require("undetected-browser");
const puppeteer = require("puppeteer");

async function init() {
  const UndetectableBMS = new UndetectableBrowser(await puppeteer.launch({ headless: false }));
  const browser = await UndetectableBMS.getBrowser();
  const page = await browser.newPage();

  //you can use any page.methods here
  //please look at example.js
}
init();

Methods

page.navigate - better navigation waiting for load detector

await page.navigate(url);

page.waitToLoad - better waiting after click handling

page.click("#someid");
await page.waitToLoad();

page.simulateMouseClick - human-like smart click with benzier mouse movements by ghost-cursor

await page.simulateMouseClick(selector | element);
ex: await page.simulateMouseClick('button[type="submit"]');

page.simulateTyping - human-like smart typing with random delays and mistakes by puppeteer-humanize

await page.simulateTyping(selector | element, text);
ex: await page.simulateTyping('input[id="username"]', "MrBeast");

page.smartWaitForSelector - it tries to find the selector. If it cannot find it it will use page.waitForSelector to wait for it. If waitForSelector timeouts it will await the amount of seconds you specify. This method does not throw errors.

await page.smartWaitForSelector(selector, delay);
ex: await page.smartWaitForSelector('button[type="submit"]', 4000); //will wait 4 seconds after it attempts to use page.waitForSelector(no error will be thrown)
await page.smartWaitForSelector('button[type="submit"]'); // Will throw an error if its unable to wait for the selector

page.$$$ - it tries to find an element in hidden document like iframes or shadow based to your selector.ALERT! It only works with iframes at the moment(no shadowroot)

await page.$$$(selector);
ex: await page.$$$('button[type="submit"]');

page.setupURLBlocker - will help you block resources urls.

await page.setupURLBlocker(urls);
ex: await page.setupURLBlocker(["test.js", ".svg", "google.com"]);

CHECKERS

page.checkFingerprint - will generate a report via pixelscan.net about the browser fingeprint. You can pass it a bool to save a screenshot of the image if the fingeprint is bad

await page.checkFingerprint(screenshot);
ex: await page.checkFingerprint(true);

page.checkCaptcha - will check your fingerprint on both Cloudflare and Arkose Captcha. Both providers are the best at detecting bots and their report will indicate how good is your scraper.

const result = await page.checkCaptcha();

page.messureSpeed - will check page latecy. You can specify an url for speedtest. If not google.com will be used

await page.messureSpeed(url);
ex: await page.messureSpeed("https://github.com/");

SCANNERS

page.scanFingerprintAttempts - Will setup a fingerprint scanner that will output every fingerprint scan attempt from a page

await page.scanFingerprintAttempts();
await page.navigate("https://browserleaks.com/canvas");

BETA METHODS

page.getElementWithInnerText - search an element based to the type of html object and the inner text Returns CDPElementHandle. The innerText must be EXACT!

await page.getElementWithInnerText(HTMLelementName, innerText);
ex: await page.getElementWithInnerText("button", "Log in");

page.getElementWithInnerHTML - search an element based to the type of html object and the innerHTML Returns CDPElementHandle. The innerHTML can be just a word as this method searches elements that contain the innerHTML you specify.

await page.getElementWithInnerHTML(HTMLelementName, innerHTML);
ex: await page.getElementWithInnerText("div", "Shop with cred");

page.clickElementWithInnerText - Will use smart mouse movement to click on element with same innerText

await page.clickElementWithInnerText(HTMLelementName, innerHTML);
ex: await page.clickElementWithInnerText("button", "Log in");

page.clickElementWithInnerHTML - Will use smart mouse movement to click on element that contain innerHTML

await page.clickElementWithInnerHTML(HTMLelementName, innerHTML);
ex: await page.clickElementWithInnerHTML("div", "<span>I love sna");

OTHER METHODS

page.enableMouseDebugWindow - used for debugging mouse movement path in a graphical way

await page.enableMouseDebugWindow();

page.sleep - used for script delays

await page.sleep(3000);

page.randomSleep - used for random script delays

await page.randomSleep(1000, 3000);

page.closeOtherPages - closes other opened pages in the browser EXCEPT the current one (usefull for cleanup)

await page.closeOtherPages();

page.repeatFunctionByAmount - will try to re-execute a function if it errors out. It also works with async functions. Its usefull when you want to repeat a function in case it errors out.

await page.repeatFunctionByAmount(functionCallback, numberOfTries, errorMessage);
ex: page.repeatFunctionByAmount(() => {
  throw new Error("error");
}, 3);

page.executeFunctionWithTimeout - this is usefull if you want to make sure your async function doesnt run forever. It will return either your async function result or "timeout"

await page.executeFunctionWithTimeout(functionCallback, timeout, customMessage);
ex: page.executeFunctionWithTimeout(() => {
  while (true) {}
}, 3000);

page.makeid - will generate a random id

await page.makeid(length);

page.getRandomInt - will generate a random int

await page.getRandomInt(min, max);

NOTES:

  • If you wish to use ghost cursor on the page object, you already have it defined it as page.cursor so you can do the following:
await page.cursor.click(selector?: string | ElementHandle, options?: ClickOptions);
await page.cursor.move(selector: string | ElementHandle, options?: MoveOptions)
await page.cursor.moveTo(destination: Vector)
  • If you wish to use @forad/puppeteer-humanize you have the typeInto function defined in page.typeInto so you can do the following:
await page.typeInto(input, text, config);

Please search those libraries for further reference.

TODO LIST

  • Shadowroot for page.$$$
  • Implement page.$$$$ (get all elements matching selector)
  • Implement smart page wait internally
  • Check fp uniqueness