我這裏想要實現的是經過轉帳到支付寶的方式判斷一個手機號是否註冊過支付寶。但查詢收款人的網絡請求很複雜分析不出來,使用 puppteer 也是沒有解決 「操做頻繁」 的問題(應該還有不少其餘的判斷我沒有考慮到),這裏只是整理記錄一下。html
問題分析
轉帳時查詢用戶是否存在會報 「操做頻繁」web
感受可能檢查了無頭瀏覽器,但在 JS 裏沒有搜索到webdrive
。而後經過內存快照找找發現真有webdrive
。。(雖然不能百分百肯定無頭瀏覽器,但以後進行了一些欺騙確實有點做用)chrome
嘗試解決
用根據 It is not possible to detect and block Chrome headless 進行欺騙:(加了一條頁面是否隱藏,感受這個也可能會檢測)瀏覽器
// We'll use Puppeteer is our browser automation framework. const puppeteer = require('puppeteer'); // This is where we'll put the code to get around the tests. const preparePageForTests = async (page) => { // Pass the User-Agent Test. const userAgent = 'Mozilla/5.0 (X11; Linux x86_64)' + 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36'; await page.setUserAgent(userAgent); // Pass the Webdriver Test. await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'webdriver', { get: () => false, }); }); // Pass the Chrome Test. await page.evaluateOnNewDocument(() => { // We can mock this in as much depth as we need for the test. window.navigator.chrome = { runtime: {}, // etc. }; }); // Pass the Permissions Test. await page.evaluateOnNewDocument(() => { const originalQuery = window.navigator.permissions.query; return window.navigator.permissions.query = (parameters) => ( parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters) ); }); // Pass the Plugins Length Test. await page.evaluateOnNewDocument(() => { // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'plugins', { // This just needs to have `length > 0` for the current test, // but we could mock the plugins too if necessary. get: () => [1, 2, 3, 4, 5], }); }); // Pass the Languages Test. await page.evaluateOnNewDocument(() => { // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'languages', { get: () => ['zh-CN', 'zh', 'en'], }); }); // 可能會檢測頁面是否隱藏,處理一下 await page.evaluateOnNewDocument(() => { // Overwrite the `hidden` property Object.defineProperty(document, "hidden", { get: () => false }); Object.defineProperty(document, "webkitHidden", { get: () => false }); }); } (async () => { // Launch the browser in headless mode and set up a page. const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: true, }); const page = await browser.newPage(); // Prepare for the tests (not yet implemented). await preparePageForTests(page); // Navigate to the page that will perform the tests. const testUrl = 'https://intoli.com/blog/' + 'not-possible-to-block-chrome-headless/chrome-headless-test.html'; await page.goto(testUrl); // Save a screenshot of the results. await page.screenshot({path: 'headless-test-result.png'}); // Clean up. await browser.close() })();
其餘博客有說用下面這種方式去掉webdriver
,但我測試很差使:網絡
const browser = await puppeteer.launch({ignoreDefaultArgs: ["--enable-automation"]});
PS:到這裏問題沒有徹底解決,查詢一兩次就頻繁了。最後使用 appium 操做支付寶的 APP 實現的(這種方式也有問題,由於用戶能夠設置不讓經過手機號查找)。。app
拓展
navigator.webdriver
屬性
有興趣的能夠看看 Chrome 添加該屬性的原因:https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/6GysDZCWwB8/rXbGoRohBgAJless
能夠根據ChromeStatus得知該屬性添加的版本爲 63,但這屬性須要到在 puppeteer v0.12.0(對應 chromium 版本爲 64.0.3240.0 (r508693))中才開始有效,在 v0.11.0(63.0.3205.0 (r499413)) 中還未生效。async
經過內存快照能夠找到任何混淆過的字符串麼?
並不能,必須待查找的內存沒有釋放(還有指向這個字符串的引用)才能找到。例如:ui
檢測不到:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <script> (function test() { var fun_a = "\167\145\142\144\162\151\166\145\162"; })(); ("\167\145\142\144\162\151\166\145\162"); var a = navigator["\167\145\142\144\162\151\166\145\162"]; console.log(a); var window.b = "\167\145\142\144\162\151\166\145\162"; delete window.b; </script> </body> </html>
能夠檢測到:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <script> var a = "\167\145\142\144\162\151\166\145\162"; function test() { var fun_a = "\167\145\142\144\162\151\166\145\162"; return navigator[fun_a]; } var b = test(); //> [...'webdriver'].map((d, i)=>String.fromCharCode(d.charCodeAt(0) + 1)).join('') //'xfcesjwfs' var other_1 = [..."xfcesjwfs"] .map((d, i) => String.fromCharCode(d.charCodeAt(0) - 1)) .join(""); </script> </body> </html>