加速乐是如何反爬的 以 cnvd 为例,访问会跳转两次,第一次返回 cookie __jsluid_s=6a027a76583f43e463722e69d0247a0a
,并且页面会通过 js 设置cookie __jsl_clearance_s=1614408251.231|-1|hWPBUGndFSVIOaYhUtUilmZPgng%3
并跳转,如图
然后带着得到的 __jsluid_s
和 __jsl_clearance_
继续访问cnvd,这里是第一次跳转,返回的是一大堆 js 代码,混淆比较严重,解混淆后还是很难审计。这段 js 的主要作用就是重新生成 __jsl_clearance_
并且会检查一些常见的爬虫特征之类的,然后跳转。
带着新生成的 cookie 第二次跳转访问 cnvd 就可以获取到真正的内容了,这个 cookie 有效时间大概有20分钟左右,而且这个 cookie 也就是 __jsl_clearance_、
__jsluid_s
有对 User-Agent 签名,cookie 和 User-Agent 是对应的。
绕过思路 原来就是通过 selenium 模拟浏览器 去访问 cnvd ,获取 cookie 和 User-Agent,但是最近这个方法不行了,在第二次访问得到的那一堆 js 代码里应该检测机制,导致 selenium 访问的时候并不会第二次跳转
解混淆后可以发现,最终设置 cookie 和跳转的代码在这,测试了一下,用 selenium+chromedriver 模拟浏览器 去访问的话根本就没有执行到这,使用正常浏览器访问的话则能够执行到这并跳转。
入口的函数是 go() ,可以看到在函数里有很多这种 if 然后 return !![] ,这里应该就是各种检测如果不满足就直接 return,
直接暴力点,把 js 代码扣出来, 然后直接把所有 return !![] 删了。让他能够执行到 设置 cookie 和 跳转的代码,设置 cookie 和跳转的代码是被包裹在 setTimeout 函数里的,会延时执行,所以还得把他从 setTimeout 扣出来。
还有一个坑,每次返回的 js 代码其实格式是有好几种的,所以正则得写好,而且我们只要获取 cookie 就行,所以把跳转的代码也直接删了。
上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 def get_cookies (self ): chrome_options = Options() chrome_options.add_argument('--no-sandbox' ) chrome_options.add_argument('--disable-dev-shm-usage' ) 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/88.0.4324.150 Safari/537.36' ) driver = webdriver.Chrome(executable_path='/pyspider/chromedriver' ,chrome_options=chrome_options) driver.get("https://www.cnvd.org.cn/" ) pageSource = driver.page_source pageSource = pageSource.split("<script>" )[1 ] pageSource = pageSource.split("</script>" )[0 ] pageSource = "var t;" +pageSource temp_pageSource = pageSource.split("setTimeout" ); temp_pageSource[-1 ] = re.sub(r'location\[.*?\](.*?)location\[.*?\](.*?)location\[.*?\](\;|\)\;|\;\}|\)\;\}),_0x(\w{3,7})\)\;' , '' ,temp_pageSource[-1 ]) pageSource = 'setTimeout' .join(temp_pageSource) pageSource = re.sub(r'_0x(\w{0,6})\[_0x(\w{0,6})\(\'0x(\w{0,6})\'\,\'.{0,6}\'\)\+\'\w{0,6}\'\]\(setTimeout\,function\(\)\{' , '' , pageSource) pageSource = re.sub(r'setTimeout\(function\(\)\{' ,'' , pageSource) pageSource = pageSource.replace("return!![];" ,"" ) ccc = driver.execute_script(pageSource+";return document.cookie" ) cj = driver.get_cookies() cookie = '' for c in cj: cookie += "'" +c['name' ] + "':'" + c['value' ] + "'," cookie = ast.literal_eval('{' +cookie+'}' ) cookie['__jsl_clearance_s' ]=ccc.split("=" )[1 ] agent = driver.execute_script("return navigator.userAgent" ) driver.quit() return cookie,agent