
Stealth Browser
- 3 installs
- 1 repo stars
- Updated February 10, 2026
- succ985/openclaw-stealth-browser
Helps with ai & agent building tasks.
About
stealth-browser is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- stealth-browser
- AI & Agent Building
- AI-coding skill
Stealth Browser by the numbers
- 3 all-time installs (skills.sh)
- Ranked #13,657 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/succ985/openclaw-stealth-browser --skill stealth-browserAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 1 |
| Last updated | February 10, 2026 |
| Repository | succ985/openclaw-stealth-browser ↗ |
What it does
Helps with ai & agent building tasks.
Files
Stealth Browser 🕵️
Bypass Cloudflare Turnstile and other anti-bot detection systems using puppeteer-extra with stealth plugin. Access websites that block headless browsers.
When to Use
- Websites protected by Cloudflare Turnstile
- Sites that block automated/headless browsers
- Need screenshots or visual content
- Require JavaScript execution and interaction
- Anti-scraping detection systems
Known Working Sites
- ✅ linux.do (Cloudflare Turnstile)
- ✅ Boss直聘 (滑块验证码)
- ✅ 拉勾网 (阿里云滑块验证)
- ✅ Most Cloudflare-protected websites
Installation
# Install dependencies
npm install puppeteer-extra puppeteer-extra-plugin-stealth
# The skill wrapper is ready to useQuick Start
Command Line
# Quick visit and screenshot
node /root/.openclaw/workspace/skills/stealth-browser/wrapper.js \
https://linux.do \
linux-do-screenshot.pngIn Code
const { quickVisit, StealthBrowser } = require('/root/.openclaw/workspace/skills/stealth-browser/wrapper.js');
// Method 1: Quick visit
const result = await quickVisit('https://linux.do', 'screenshot.png');
console.log(result);
// { success: true, title: 'LINUX DO - ...', screenshotPath: '...' }
// Method 2: Full control
const browser = new StealthBrowser();
await browser.launch();
await browser.goto('https://linux.do');
const title = await browser.getTitle();
await browser.screenshot('homepage.png');
await browser.close();In Subagent
const { quickVisit } = require('/root/.openclaw/workspace/skills/stealth-browser/wrapper.js');
const result = await quickVisit('https://linux.do', 'linux-do.png');
if (result.success) {
// Send screenshot via message tool
message({
action: "send",
channel: "telegram",
media: result.screenshotPath,
message: "Linux.do homepage"
});
}API Reference
quickVisit(url, filename)
Quick visit a website and take a screenshot.
Parameters:
url(string): Target URLfilename(string): Screenshot filename
Returns:
{
success: boolean,
title: string,
screenshotPath: string
}StealthBrowser Class
Constructor
new StealthBrowser(options)Options:
headless: 'new' | true | false (default: 'new')viewport: { width, height } (default: { width: 1920, height: 1080 })userAgent: string (default: Chrome 131)screenshotPath: string (default: '/root/.openclaw/media/browser/')
Methods
launch()- Start browsergoto(url, options?)- Navigate to URLscreenshot(filename)- Take screenshotgetTitle()- Get page titlegetContent()- Get HTML contentevaluate(fn, ...args)- Execute JavaScriptcheckSuccess(keywords)- Check if visit succeededclose()- Close browservisitAndScreenshot(url, filename)- Shortcut method
How It Works
Why OpenClaw Default Browser Fails
1. navigator.webdriver = true - Explicitly identifies as automated browser 2. Uses legacy headless mode with obvious fingerprints 3. Missing real browser fingerprints 4. No plugin list or language settings
How StealthPlugin Solves It
1. Hides automation indicators:
- Changes
navigator.webdrivertoundefined - Overrides
Function.prototype.toString - Fixes iframe detection
2. Mimics real fingerprints:
- Adds real plugin list
- Simulates language settings
- Fixes
window.outerWidth/Height - Adds touch support
3. Uses new headless mode:
headless: 'new'uses real Chrome rendering engine- Much harder to detect
4. Disables automation features:
--disable-blink-features=AutomationControlled--no-sandbox--disable-setuid-sandbox
Detection Point Comparison
| Detection Point | OpenClaw Default | StealthPlugin |
|---|---|---|
| navigator.webdriver | true ❌ | undefined ✅ |
| headless fingerprints | obvious ❌ | hidden ✅ |
| browser fingerprints | missing ❌ | complete ✅ |
| plugin list | empty ❌ | real ✅ |
| window.outerWidth | 0 ❌ | 1920 ✅ |
Examples
Example 1: Basic Visit
const { StealthBrowser } = require('/root/.openclaw/workspace/skills/stealth-browser/wrapper.js');
const browser = new StealthBrowser();
await browser.launch();
await browser.goto('https://linux.do');
const title = await browser.getTitle();
console.log('Title:', title);
await browser.screenshot('linux-do.png');
await browser.close();Example 2: Multiple Pages
const { StealthBrowser } = require('/root/.openclaw/workspace/skills/stealth-browser/wrapper.js');
const browser = new StealthBrowser();
await browser.launch();
const urls = [
'https://linux.do',
'https://linux.do/latest',
'https://linux.do/c/develop/4'
];
for (const url of urls) {
await browser.goto(url);
const title = await browser.getTitle();
console.log('Title:', title);
const filename = url.replace(/https?:\/\/|\/$/g, '').replace(/\//g, '-') + '.png';
await browser.screenshot(filename);
}
await browser.close();Example 3: Custom Configuration
const { StealthBrowser } = require('/root/.openclaw/workspace/skills/stealth-browser/wrapper.js');
const browser = new StealthBrowser({
headless: 'new',
viewport: { width: 2560, height: 1440 },
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
});
await browser.goto('https://linux.do', { waitMs: 5000 });
const content = await browser.getContent();
console.log('Content length:', content.length);
await browser.close();Known Issues
1. Requires graphics environment: Headed mode needs X server 2. Resource intensive: More resource usage than pure text fetching 3. Slower speed: Requires launching full browser
Alternative Solutions
If you only need text content, consider using r.jina.ai proxy:
curl -s "https://r.jina.ai/http://linux.do/latest"Pros:
- Faster
- Lighter
- 100% reliable
Cons:
- Cannot take screenshots
- Cannot interact
- Depends on third-party service
Files
wrapper.js- Main wrapper scriptexamples.js- Usage examplesREADME.md- Detailed documentation
Changelog
- 2026-02-11: Created skill with puppeteer-extra + stealth plugin
- 2026-02-11: Successfully bypassed Cloudflare Turnstile on linux.do
- 2026-02-11: Added comprehensive API and examples
References
node_modules/
*.log
.DS_Store
*.png
*.jpg
*.jpeg
*.gif
media//**
* 使用示例:访问linux.do
*/
const { StealthBrowser, quickVisit } = require('./browser-stealth-wrapper.js');
async function example1_basic() {
console.log('\n=== 示例1: 基础访问 ===');
const browser = new StealthBrowser();
try {
// 启动浏览器
await browser.launch();
// 访问网站
await browser.goto('https://linux.do');
// 获取标题
const title = await browser.getTitle();
console.log('页面标题:', title);
// 截图
await browser.screenshot('linux-do-homepage.png');
// 检查是否成功
const { success } = await browser.checkSuccess(['linux.do', 'LINUX DO']);
console.log('访问结果:', success ? '✅ 成功' : '❌ 失败');
// 关闭浏览器
await browser.close();
} catch (error) {
console.error('错误:', error.message);
await browser.close();
}
}
async function example2_quick() {
console.log('\n=== 示例2: 快捷访问 ===');
try {
const result = await quickVisit('https://linux.do', 'linux-do-quick.png');
console.log('访问结果:', result);
} catch (error) {
console.error('错误:', error.message);
}
}
async function example3_multiple() {
console.log('\n=== 示例3: 多页面访问 ===');
const browser = new StealthBrowser();
try {
await browser.launch();
const urls = [
'https://linux.do',
'https://linux.do/latest',
'https://linux.do/c/develop/4'
];
for (const url of urls) {
console.log(`\n访问: ${url}`);
await browser.goto(url);
const title = await browser.getTitle();
console.log('标题:', title);
const filename = url.replace(/https?:\/\//, '').replace(/\//g, '-') + '.png';
await browser.screenshot(filename);
}
await browser.close();
} catch (error) {
console.error('错误:', error.message);
await browser.close();
}
}
async function example4_custom() {
console.log('\n=== 示例4: 自定义配置 ===');
const browser = new StealthBrowser({
headless: 'new',
viewport: { width: 2560, height: 1440 },
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
});
try {
await browser.goto('https://linux.do', { waitMs: 5000 });
const content = await browser.getContent();
console.log('页面内容长度:', content.length);
await browser.close();
} catch (error) {
console.error('错误:', error.message);
await browser.close();
}
}
// 运行所有示例
async function runAll() {
await example1_basic();
await new Promise(resolve => setTimeout(resolve, 2000));
await example2_quick();
await new Promise(resolve => setTimeout(resolve, 2000));
await example3_multiple();
await new Promise(resolve => setTimeout(resolve, 2000));
await example4_custom();
}
// 如果直接运行
if (require.main === module) {
const example = process.argv[2] || 'all';
switch (example) {
case '1':
example1_basic();
break;
case '2':
example2_quick();
break;
case '3':
example3_multiple();
break;
case '4':
example4_custom();
break;
case 'all':
default:
runAll();
}
}
module.exports = { example1_basic, example2_quick, example3_multiple, example4_custom };MIT License
Copyright (c) 2026 Claws
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.Stealth Browser Skill
Bypass Cloudflare Turnstile and other anti-bot detection using puppeteer-extra + stealth plugin.
Quick Start
# Install dependencies
npm install puppeteer-extra puppeteer-extra-plugin-stealth
# Quick visit
node wrapper.js https://linux.do screenshot.pngUsage
See SKILL.md for detailed documentation.
Examples
# Run all examples
node examples.js all
# Run specific example
node examples.js 1
node examples.js 2
node examples.js 3
node examples.js 4Features
- ✅ Bypass Cloudflare Turnstile
- ✅ Bypass slider captchas
- ✅ Screenshot support
- ✅ JavaScript execution
- ✅ Full browser control
Files
SKILL.md- Complete documentationwrapper.js- Main wrapper scriptexamples.js- Usage examplesREADME.md- This file
/**
* Stealth Browser Wrapper
*
* 使用puppeteer-extra + stealth插件绕过Cloudflare等反爬检测
* 提供简单的API供其他脚本调用
*/
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const fs = require('fs');
const path = require('path');
// 使用stealth插件
puppeteer.use(StealthPlugin());
class StealthBrowser {
constructor(options = {}) {
this.browser = null;
this.page = null;
this.options = {
headless: options.headless ?? 'new',
viewport: options.viewport ?? { width: 1920, height: 1080 },
userAgent: options.userAgent ?? 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
screenshotPath: options.screenshotPath ?? '/root/.openclaw/media/browser/',
...options
};
}
/**
* 启动浏览器
*/
async launch() {
if (this.browser) {
console.log('浏览器已启动');
return this;
}
console.log('启动stealth浏览器...');
this.browser = await puppeteer.launch({
headless: this.options.headless,
args: [
'--disable-blink-features=AutomationControlled',
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security',
'--disable-features=VizDisplayCompositor'
]
});
this.page = await this.browser.newPage();
await this.page.setUserAgent(this.options.userAgent);
await this.page.setViewport(this.options.viewport);
console.log('✅ 浏览器启动成功');
return this;
}
/**
* 访问URL
*/
async goto(url, options = {}) {
if (!this.page) {
await this.launch();
}
console.log(`访问: ${url}`);
const gotoOptions = {
waitUntil: options.waitUntil ?? 'networkidle2',
timeout: options.timeout ?? 30000,
...options
};
await this.page.goto(url, gotoOptions);
// 等待页面加载
if (options.waitMs) {
await new Promise(resolve => setTimeout(resolve, options.waitMs));
} else {
await new Promise(resolve => setTimeout(resolve, 3000));
}
return this;
}
/**
* 截图
*/
async screenshot(filename) {
if (!this.page) {
throw new Error('浏览器未启动');
}
const filepath = path.join(this.options.screenshotPath, filename);
await this.page.screenshot({ path: filepath });
console.log(`✅ 截图已保存: ${filepath}`);
return filepath;
}
/**
* 获取页面标题
*/
async getTitle() {
if (!this.page) {
throw new Error('浏览器未启动');
}
return await this.page.title();
}
/**
* 获取页面内容(HTML)
*/
async getContent() {
if (!this.page) {
throw new Error('浏览器未启动');
}
return await this.page.content();
}
/**
* 执行JavaScript
*/
async evaluate(fn, ...args) {
if (!this.page) {
throw new Error('浏览器未启动');
}
return await this.page.evaluate(fn, ...args);
}
/**
* 检查是否成功访问(通过标题判断)
*/
async checkSuccess(expectedKeywords) {
const title = await this.getTitle();
const keywords = Array.isArray(expectedKeywords) ? expectedKeywords : [expectedKeywords];
const success = keywords.some(keyword =>
title.toLowerCase().includes(keyword.toLowerCase())
);
return { success, title };
}
/**
* 关闭浏览器
*/
async close() {
if (this.browser) {
await this.browser.close();
this.browser = null;
this.page = null;
console.log('浏览器已关闭');
}
}
/**
* 快捷方法:访问并截图
*/
async visitAndScreenshot(url, filename) {
await this.goto(url);
await this.screenshot(filename);
const { success, title } = await this.checkSuccess([url, 'linux.do', 'LINUX DO']);
await this.close();
return { success, title, screenshotPath: path.join(this.options.screenshotPath, filename) };
}
}
/**
* 快捷函数:快速访问网站并截图
*/
async function quickVisit(url, filename) {
const browser = new StealthBrowser();
return await browser.visitAndScreenshot(url, filename);
}
module.exports = { StealthBrowser, quickVisit };
// 如果直接运行此文件
if (require.main === module) {
const url = process.argv[2] || 'https://linux.do';
const filename = process.argv[3] || 'stealth-visit.png';
console.log('快速访问模式');
quickVisit(url, filename)
.then(({ success, title, screenshotPath }) => {
console.log('访问结果:', { success, title, screenshotPath });
process.exit(success ? 0 : 1);
})
.catch(error => {
console.error('错误:', error.message);
process.exit(1);
});
}