前段时间发过一篇文章是隐藏: Selenium中window.navigator.webdriver的,但是selenium启动的chrome不仅仅只有这一个特性,所以光移除window.navigator.webdriver并不能完全隐藏selenium的特征.
方法一:使用mitmproxy来修改js文件:
安装mitmproxy
pip install mitmproxy
分析目标网站的js是怎么识别指纹特征的
编写干扰脚本DriverPass.py:
import re from mitmproxy import ctx def response(flow): if '/js/yoda.' in flow.request.url: for webdriver_key in ['webdriver', '__driver_evaluate', '__webdriver_evaluate', '__selenium_evaluate', '__fxdriver_evaluate', '__driver_unwrapped', '__webdriver_unwrapped', '__selenium_unwrapped', '__fxdriver_unwrapped', '_Selenium_IDE_Recorder', '_selenium', 'calledSelenium', '_WEBDRIVER_ELEM_CACHE', 'ChromeDriverw', 'driver-evaluate', 'webdriver-evaluate', 'selenium-evaluate', 'webdriverCommand', 'webdriver-evaluate-response', '__webdriverFunc', '__webdriver_script_fn', '__$webdriverAsyncExecutor', '__lastWatirAlert', '__lastWatirConfirm', '__lastWatirPrompt', '$chrome_asyncScriptInfo', '$cdc_asdjflasutopfhvcZLmcfl_' ]: ctx.log.info('Remove "{}" from {}.'.format( webdriver_key, flow.request.url )) flow.response.text = flow.response.text.replace('"{}"'.format(webdriver_key), '"NO-SUCH-ATTR"') flow.response.text = flow.response.text.replace('t.webdriver', 'false') flow.response.text = flow.response.text.replace('ChromeDriver', '')
启动中间代理
mitmdump -s DriverPass.py -p 8001
selenium代码
from selenium import webdriver from time import sleep chromeOptions = webdriver.ChromeOptions() # 设置代理 chromeOptions.add_argument("--proxy-server=http://127.0.0.1:8001") browser = webdriver.Chrome('D:/chromedriver.exe', chrome_options=chromeOptions) # 查看本机ip,查看代理是否起作用 browser.get("http://cip.cc") sleep(20) # 退出,清除浏览器缓存 browser.quit()
方法二: 使用stealth.min.js来实现
因为有人为Node.js 版本的 puppeteer写了一套叫做puppeteer-extra-plugin-stealth的插件,它可以让puppeteer 隐藏模拟浏览器的指纹特征。那么其他语言怎么来使用呢? 插件作者还写了另外一个工具叫extract-stealth-evasions,是用来生成stealth.min.js文件的.
(生成这一步需要梯子,要不然会很慢很慢,甚至无法成功)
我们需要node环境,使用npx来生成.
npx extract-stealth-evasions
已生成的下载:stealth.min.js
测试代码:
from time import sleep from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument( 'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36') driver = Chrome('D:/chromedriver.exe', options=chrome_options) with open('D:/abc/stealth.min.js') as f: js = f.read() driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": js }) driver.get('https://bot.sannysoft.com/') sleep(5) driver.save_screenshot('pic.png') #模拟在A页面新打开一个标签页 driver.execute_script("window.open('https://bot.sannysoft.com/')") sleep(5) windows = driver.window_handles driver.switch_to.window(windows[-1]) driver.save_screenshot('pic2.png') sleep(2) driver.quit()
其实原理还是调用chrome的Page.addScriptToEvaluateOnNewDocument方法,在运行网页本身的js之前先运行我们的js代码.
缺点: 如果网页是在一个新的标签中打开的,经过我的测试chrome的Page.addScriptToEvaluateOnNewDocument不会对新打开的标签执行我们的js代码.如果这个页面有检测代码的话我们就暴露了.
测试结果:
1. pic.png
2. pic.png
在新标签中明显检测到了我们.
方法三:利用selenium连接chrome的远程调试端口
我们需要找到chrome在本机上的位置, 然后进入文件夹执行命令:
需要关闭所有打开的chrome,然后再用命令打开!
chrome.exe --remote-debugging-port=9222 --user-data-dir="D:\temp\"
selenium连接chrome
from time import sleep from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options chrome_options = Options() # 不要拦截弹出框 chrome_options.add_argument(" --disable-popup-blocking ") chrome_options.add_argument( 'user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36') chrome_options.add_experimental_option('debuggerAddress', '127.0.0.1:9222') driver = Chrome('D:/chromedriver.exe', options=chrome_options) driver.get('https://bot.sannysoft.com/') sleep(5) driver.save_screenshot('pic.png') # 模拟在A页面新打开一个标签页 driver.execute_script("window.open('https://bot.sannysoft.com/')") sleep(5) windows = driver.window_handles driver.switch_to.window(windows[-1]) driver.save_screenshot('pic2.png') sleep(2) driver.quit()
这样保存的两张截图是一样的,和上面的pic.png一致,证明没有被检测出来!
此方法虽然笨了点,但却是最有效的方法! 因为chrome本身就是我们自己启动的,没有加载任何Selenium的指纹特征.
方法四:使用undetected_chromedriver
import undetected_chromedriver as uc from selenium import webdriver from time import sleep options = webdriver.ChromeOptions() options.add_argument("start-maximized") driver = uc.Chrome(options=options) driver.get('https://bot.sannysoft.com/') sleep(5) driver.save_screenshot('pic.png') # 模拟在A页面新打开一个标签页 driver.execute_script("window.open('https://bot.sannysoft.com/')") sleep(5) windows = driver.window_handles driver.switch_to.window(windows[-1]) driver.save_screenshot('pic2.png') sleep(2) driver.quit()
参考文章:
还没有评论,来说两句吧...