selenium打开网页被检测,怎么屏蔽和绕过

Posted fengzhilanyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了selenium打开网页被检测,怎么屏蔽和绕过相关的知识,希望对你有一定的参考价值。

Selenium 操作被检测屏蔽

selenium打开浏览器模仿人工操作是诸多爬虫小白最万能的网页数据获取方式,但是在做自动化爬虫时,经常被检测到是selenium驱动。前段时间selenium打开维普高级搜索时得到的页面是空白页。

Selenium为何会被检测

主要原因是selenium打开的浏览器指纹和人工操作打开的浏览器指纹是不同的,比如最熟知的window.navigator.webdriver关键字,在selenium打开的浏览器打印返回结果为true,而正常浏览器打印结果返回为undefined,我们可以在
网站比较各关键字。

Selenium防检测方法

1. 修改window.navigator.webdriver关键字返回结果

from selenium import webdriver
options = webdriver.ChromeOptions()
# 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", 
            "source": """
            Object.defineProperty(navigator, 'webdriver', 
              get: () => undefined
            )
            """
        )

但是因为浏览器指纹很多,这种方法的局限性是显而易见的。

2. 使用stealth.min.js文件防止selenium被检测

import time
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
driver = Chrome('./chromedriver', options=chrome_options)

with open('/Users/kingname/test_pyppeteer/stealth.min.js') as f:
    js = f.read()

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", 
  "source": js
)

stealth.min.js文件来源于puppeteer,有开发者给 puppeteer 写了一套插件,叫做puppeteer-extra。其中,就有一个插件叫做puppeteer-extra-plugin-stealth专门用来让 puppeteer 隐藏模拟浏览器的指纹特征。

python开发者就需要把其中的隐藏特征的脚本提取出来,做成一个 js 文件。然后让 Selenium 或者 Pyppeteer 在打开任意网页之前,先运行一下这个 js 文件里面的内容。

puppeteer-extra-plugin-stealth的作者还写了另外一个工具,叫做extract-stealth-evasions。这个东西就是用来生成stealth.min.js文件的。

stealth.min.js资源:
链接:https://pan.baidu.com/s/1wiFnwOlHx3Wxe1UzW5gdrg
提取码:6hqf

3. undetected_chromedriver

undetected_chromedriver
使用方法
undetected_chromedriver 可以防止浏览器特征被识别,并且可以根据浏览器版本自动下载驱动。

import undetected_chromedriver as uc
driver = uc.Chrome()
driver.get('https://nowsecure.nl')

这是目前在用的一种方法,基本可以解决selenium被识别的问题

突破网站对selenium的屏蔽

使用selenium模拟浏览器进行数据抓取无疑是当下最通用的数据采集方案,它通吃各种数据加载方式,能够绕过客户JS加密,绕过爬虫检测,绕过签名机制。它的应用,使得许多网站的反采集策略形同虚设。由于selenium不会在HTTP请求数据中留下指纹,因此无法被网站直接识别和拦截。

这是不是就意味着selenium真的就无法被网站屏蔽了呢?非也。selenium在运行的时候会暴露出一些预定义的Javascript变量(特征字符串),例如"window.navigator.webdriver",在非selenium环境下其值为undefined,而在selenium环境下,其值为true(如下图所示为selenium驱动下Chrome控制台打印出的值)。

技术图片
在启动Chromedriver之前,为Chrome开启实验性功能参数excludeSwitches,它的值为[enable-automation], 完整代码如下:

----------------------------------------
from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions
option =ChromeOptions()
option.add_experimental_option(excludeSwitches, [enable-automation])
driver = Chrome(options = option)
----------------------------------------
此时运行selenium,并且在浏览器中输入window.navigator.webdriver发现其值已变为undefined
另一种解决办法

技术图片

除此之外,还有一些其它的标志性字符串(不同的浏览器可能会有所不同),常见的特征串如下所示:

  1. webdriver  
  2. __driver_evaluate  
  3. __webdriver_evaluate  
  4. __selenium_evaluate  
  5. __fxdriver_evaluate  
  6. __driver_unwrapped  
  7. __webdriver_unwrapped  
  8. __selenium_unwrapped  
  9. __fxdriver_unwrapped  
  10. _Selenium_IDE_Recorder  
  11. _selenium  
  12. calledSelenium  
  13. _WEBDRIVER_ELEM_CACHE  
  14. ChromeDriverw  
  15. driver-evaluate  
  16. webdriver-evaluate  
  17. selenium-evaluate  
  18. webdriverCommand  
  19. webdriver-evaluate-response  
  20. __webdriverFunc  
  21. __webdriver_script_fn  
  22. __$webdriverAsyncExecutor  
  23. __lastWatirAlert  
  24. __lastWatirConfirm  
  25. __lastWatirPrompt  
  26. $chrome_asyncScriptInfo  
  27. $cdc_asdjflasutopfhvcZLmcfl_  

了解了这个特点之后,就可以在浏览器客户端JS中通过检测这些特征串来判断当前是否使用了selenium,并将检测结果附加到后续请求之中,这样服务端就能识别并拦截后续的请求。

下面讲一个具体的例子。

鲲之鹏的技术人员近期就发现了一个能够有效检测并屏蔽selenium的网站应用:大众点评网的验证码表单页,如果是正常的浏览器操作,能够有效的通过验证,但如果是使用selenium就会被识别,即便验证码输入正确,也会被提示“请求异常,拒绝操作”,无法通过验证(如下图所示)。

技术图片

分析页面源码,可以找到 https://static.meituan.net/bs/yoda-static/file:file/d/js/yoda.e6e7c3988817eb17.js 这个JS文件,将代码格式化后,搜索webdriver可以看到如下代码:

技术图片

 可以看到它检测了"webdriver", "__driver_evaluate", "__webdriver_evaluate"等等这些selenium的特征串。提交验证码的时候抓包可以看到一个_token参数(很长),selenium检测结果应该就包含在该参数里,服务端借以判断“请求异常,拒绝操作”。

现在才进入正题,如何突破网站的这种屏蔽呢?

我们已经知道了屏蔽的原理,只要我们能够隐藏这些特征串就可以了。但是还不能直接删除这些属性,因为这样可能会导致selenium不能正常工作了。我们采用曲线救国的方法,使用中间人代理,比如fidder, proxy2.py或者mitmproxy,将JS文件(本例是yoda.*.js这个文件)中的特征字符串给过滤掉(或者替换掉,比如替换成根本不存在的特征串),让它无法正常工作,从而达到让客户端脚本检测不到selenium的效果。

下面我们验证下这个思路。这里我们使用mitmproxy实现中间人代理),对JS文件(本例是yoda.*.js这个文件)内容进行过滤。启动mitmproxy代理并加载response处理脚本:

  1. mitmdump.exe -S modify_response.py  

其中modify_response.py脚本如下所示:

view plaincopy to clipboardprint?

# coding:utf-8
# modify_response.py

import re
from mitmproxy import ctx

def response(flow):

    """修改应答数据"""
    if ‘/js/yoda.‘ in flow.request.url:
        # 屏蔽selenium检测
        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‘,‘‘)

在selnium中使用该代理(mitmproxy默认监听127.0.0.1:8080)访问目标网站,mitmproxy将过滤JS中的特征符串,如下图所示:

技术图片

经多次测试,该方法可以有效的绕过大众点评的selenium检测,成功提交大众点评网的验证码表单。

 

转载自:http://www.site-digger.com/html/articles/20180821/653.html

以上是关于selenium打开网页被检测,怎么屏蔽和绕过的主要内容,如果未能解决你的问题,请参考以下文章

微信屏蔽网址解决办法 如何恢复微信访问拦截 微信网页拦截怎么办

QQ/微信里被禁止访问的网页怎么处理 被屏蔽的域名如何正常访问

微信分享朋友圈的链接被屏蔽(已停止访问该网页)怎么办?

网址在QQ微信被拦截怎么办 怎么样才能让被微信屏蔽的网址正常访问

QQ/微信中被禁止访问的网页怎么打开

求助:这个网站不允许在新的窗口打开网页