解决selenium无法得到全量的cookie问题

解决selenium无法得到全量的cookie

某爬虫工程师:selenium无法得到全量的cookie?这是什么问题?我用起来没问题啊。嗯,是的。如果你仅仅抓取单域名网站很可能遇不到这个问题,仅仅通过webDriver.manage().getCookies()这个方法就可以获取cookie。selenium无法得到全量的cookie的场景:

多域名网站群。实战场景举例:当年我在某互金公司做淘宝、支付宝网站用户信息抓取的项目的时候,用户会通过我们爬虫服务api传给我们账户/密码或者扫码我们劫持的淘宝登录二维码。这样我们服务器的爬虫就可以模拟完成用户登录,大家应该知道从淘宝的个人中心页面点击“账户余额”可以直接跳转到支付宝页面对吧!我们用selenium模拟点击账户余额跳转到支付宝,这时候支付宝给浏览器也种了支付宝登录状态的cookie。好,这时候浏览器相当于淘宝+支付宝的cookie我们都有了。但是当我们通过webDriver.manage().getCookies()获取cookie的时候。我们发现我们只能获取支付宝的cookie,而当前浏览器停留在支付宝页面*.alipay.com/xxx。当我们回到淘宝页面的时候再次webDriver.manage().getCookies()发现又只能获取taobao.com的cookie。先不追究webdriver的底层原因,我们按这个现象就可以知道selenium无法获取全量cookie。其实也很好理解为什么webdriver底层不愿意给你浏览器浏览过的全量cookie,因为selenium最初设计是做一个自动化网页测试工具,人家并不是给你做爬虫用的。是很多爬虫工程看到了selenium在爬虫场景的威力,才把它当成一个“爬虫工具”。其实网上也有人遇到过这样的问题
解决selenium无法得到全量的cookie问题_第1张图片

大家都是怎么克服的?一般有以下三种方案

1、干脆直接不获取cookie了,从头到尾直接用selenium进行采集。(但是这样你就会很慢…,只要你的业务场景能够容忍你这样慢。OK!没问题!)

2、定制浏览器,基于webkit或者chromium开发自己爬虫浏览器。(这种方式,我觉得,你挺猛阿。c/c++玩的这么溜。最后大多数人都是失败告终,或者做出来的工具api体验度跟selenium比就跟屎一样。)

3、在selenium浏览器前面设置一个中间人攻击代理,因为中间人代理可以监控http(s)的发出request.headers和response.headers。从headers拦截cookie记录下来。(这种也是我一直用的方法,很投机取巧吧。付出最少的努力,就可以达到比方案二更稳定的效果。)

中间人代理获取全量cookie在goniub的实践

第一步是中间人代理技术选型,目前市面上的中间人代理有:mitmproxy(python)、LittleProxy(java)、Browsermob-Proxy(java)、等等还有其他更小众的。其中最mitmproxy是最稳定且功能最全。LittleProxy至今4年未更新。Browsermob-Proxy在LittleProxy的基础上进行了API封装,并支持Restful管理方式。但是自从LittleProxy不更新,Browsermob-Proxy也不更新了,使用起来有许多bug。所以mitmproxy就是goniub最好的选择。

第二步是跨语言集成。mitmproxy是python写的,goniub是服务于java爬虫工程师的项目。那么java如何驾驭python实现的mitmproxy。由此goniub采用了grpc + proto3实现java和python跨语言调用。而mitmproxy实例管理goniub引入了mitmproxy-hub的概念。就是一个python进程内可以开启多个mitmproxy实例,基于java通过grpc调用mitmproxy内部api进行实例管理。原理图如下:
解决selenium无法得到全量的cookie问题_第2张图片

第三步是模块化拆分。既然java中Browsermob-Proxy已经日落西山了,索性作者就把mitmproxy-java和单独拆分出来,跟着mitmproxy-hub一起。mitmproxy-hub其定义了和外部通信的proto3接口,今后方便继续扩展c++、golang、php等语言。作者并不能写一个像mitmproxy那样优秀的项目,但是他懂得用优雅的方式站在巨人的肩膀上。

获取selenium全量cookie示例步骤:

1、启动远端的mitmproxy-hub服务

git clone https://github.com/CreditTone/mitmproxy-hub.git
cd mitmproxy-hub/mitmproxy-hub/
python3 server.py//port of the service default on 60051

2、java项目依赖mitmproxy-java

		<dependency>
			<groupId>com.deep007groupId>
			<artifactId>mitmproxy-javaartifactId>
			<version>1.0.6version>
		dependency>

3、准备就绪,发车…

	public static void main(String[] args) throws InterruptedException {
		RemoteMitmproxy remoteMitmproxy = new RemoteMitmproxy("127.0.0.1", 60051, "127.0.0.1", 8866);
		CookieCollectFilter cookieCollectFilter = new CookieCollectFilter();
		remoteMitmproxy.addFlowFilter(cookieCollectFilter);
		remoteMitmproxy.start();
		HttpsProxy httpsProxy = new HttpsProxy("127.0.0.1", 8866);
		System.out.println("启动浏览器");
		System.out.println("使用代理" + httpsProxy.getServer() + ":" + httpsProxy.getPort());
		GoniubChromeDriver chromeDriver = GoniubChromeDriver.newInstance(true, true, true, httpsProxy, GoniubChromeOptions.CHROME_USER_AGENT);
		chromeDriver.get("https://www.taobao.com");
		//登录逻辑省略。。。。。。。阿巴阿巴
		//跳转到支付宝代码省略。。。。。。阿巴阿巴
		for (Cookie cookie : cookieCollectFilter.catchCookies) {
			System.out.println(cookie.getDomain() + ">>>"+ cookie.getName()+"="+cookie.getValue() +" path:"+cookie.getPath());
		}
		//此处将打印浏览器历史sent和receive所有的cookie
		remoteMitmproxy.stop();
		chromeDriver.quit();
}

你可能感兴趣的:(goniub,爬虫,GuozhongCrawler,selenium,java)