在linux centos7上通过selenium、chromedriver实现网站(京东、西集、考拉)自动签到
centos7安装chrome
腾讯云服务器,操作系统centos7.4,安装chrome使用npm方式。
步骤如下:
- 去https://www.chrome64bit.com/index.php/google-chrome-64-bit-for-linux下载包 https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
- 安装rz sz命令: sudo yum install lrzsz -y
- 上传安装包,安装以下依赖:
- yum -y install redhat-lsb
- yum install libXss* -y
- yum install libappindicator-gtk3
- 解压安装chrome:rpm -ivh google-chrome-stable_current_x86_64.rpm
chrome默认安装目录/opt/google/chrome
可以用如下命令测试是否安装成功:google-chrome-stable --no-sandbox --headless --disable-gpu --screenshot https://www.baidu.com/
安装成功会在当前目录生成百度首页截图(会报一个错,但没什么影响,是个缺少UI的提示),将截图下载到windows机器,打开看到字体都是乱码。这个乱码对后来的脚本运行造成了很大误导。后面会详说。
遇到的问题:
- 缺少相关依赖,逐个进行安装
- 现在chrome最低支持centos7。centos6上的一些安装脚本或方案均已失效,本想在公司测试机6.9上安装,搜了一些资料最后发现是徒劳。甚至之前在6上能绕过一些限制安装chrome的脚本的作者在他网站上声明,该脚本已死,不要再联系他了。
- 7上的一些依赖都是无法在6上安装的,yum找不到对应的库
- centos6可以考虑安装chromium
安装chromedriver
需要注意的是chromedriver必须要与chrome版本对应,否则不能正常工作。我这里安装的是chrome68,对应的是chromedriver版本是2.41
对应关系和下载地址,百度就可以看到。下面地址仅供参考,随时失效
测试chromedriver:
[root@VM_0_11_centos chrome]# ./chromedriver
Starting ChromeDriver 2.41.578700 (2f1ed5f9343c13f73144538f15c00b370eda6706) on port 9515
Only local connections are allowed.
如上说明启动成功。这里./chromediver --help可以查看命令使用说明。如果有报错信息,可以加上参数./chromedriver --verbose输出详细日志。
我在这里遇到一个问题,查了很久,运行./chromedriver命令后,一直报错,报一个[SERVER]中间一长串英文(99),记不住了,查了很久无果,最后打开verbose参数,提示了一个IPV6什么的错误,就把系统的ipv6地址设置打开了,命令是:sysctl -w net.ipv6.conf.all.disable_ipv6=0,之后就不再报错了。但后来通过selenium运行的时候发现,不必理会该报错。
运行selenium程序
此处值得说明是,chromeDriver需要设置一些options,代码如下:
System.setProperty("webdriver.chrome.driver", "/opt/google/chrome/chromedriver");
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--no-sandbox");
options.addArguments("--disable-gpu");
options.addArguments("--window-size=1920,1080");
ChromeDriver driver = new ChromeDriver(options);
遇到的问题
现象:xiji网可以正常登录,但kaola、jd就失败,登录不成功
结论:某些网站有安全验证机制,比如网易,如果登录IP非常用IP,会弹出验证码。京东则会有一个中间页提示安全信息。
说说错误
考拉的问题:
因为xiji的成功,加上截图里的乱码,一直以为是字符编码的问题,导致用户名密码错误,服务器不认。于是又是设置系统语言,又是安装字体,设置java文件编码,设置都没有效果。
京东的问题:
京东登录失败的问题在于,用用户名登陆后跳到了一个中间页,提示有安全风险,要我去绑定手机,但我手机已经绑定了,如果直接用手机号+密码登录就没问题。估计也是IP变化造成的问题。
下面我说说怎么定位问题的。
chrome remote debug
这是chrome的一个debug功能,可以用来在别的机器或chrome里debug无头chrome。
输入命令:
STEP1:在远程机器(云服务器)上执行:
google-chrome-stable --no-sandbox --headless --disable-gpu --remote-debugging-port=9222 https://m.kaola.com/login.html
如此就在9222上监听了chrome的debug端口
STEP2:这里需要注意,上述操作只是chrome在本地暴露一个地址,远程是无法访问的,在windows机器上打开http://ip:9222是无法访问的,此时需要在云服务器上做一个端口映射,这里使用ssh命令
ssh -L 0.0.0.0:9223:localhost:9222 localhost -N
STEP3:
在chrome地址栏里输入http://ip:9223 能看到当前chrome debug信息,输入http://ip:9223/json 能看到一些相信信息,这里暴露了一个websocket的调试地址
http://ip:9223/devtools/devtools.html?ws://ip:9223/devtools/page/ADE6C8375C62850FDD7C951260626600
这个地址是给websorcket用的,可能需要一些开发才能使用,这里没有深入。只作了解
STEP4:
在windows机器上打开chrome,地址栏输入
chrome://inspect/#devices
先在第一个红框处,配置服务器ip,当chrome检测到的时候,就会在remote target里出现一个Target,点击第二个红框,inspect,就进入debug模式了,就会打开一个窗口,里面就是在云服务上运行的chrome界面,地址是上面配置的https://m.kaola.com/login.html
这种方案的缺点主要有两个:
- 网页乱码。但实际上并非乱码,代码完全跑的通,用浏览器F12看源码字体也不是乱码,为什么网页渲染乱码,更深入的原因查不到
- 操作延迟高,有的网站还算流畅,有的网站就很卡,做一个 操作延迟很久,影像正常操作。只能做一些基本验证。
通过这种方案,我检查到了为什么考拉总是登录失败的原因。我发现,kaola登录的时候总是提示滑动验证码,原来是ip不合法了,想必是第一次的时候就发现不是常用ip,让输入滑动验证码,之后一直尝试登录,ip可能被拉黑了。
京东的问题是,点击登录,跳到了一个中间页,提示手机绑定安全之类的,后来改为手机号登录就没问题了。
通过remote debug方式,找到了登录失败的原因,下面看看怎么解决ip被封的问题。
使用squid代理
一般来说,服务器拉黑ip的几种情况
- 短时间频繁访问
- 密码多次输入错误
- 非常用ip登录
如何让ip解封?大概有几种:
- 输入正确密码,等待服务器解封
- 换一个账号试试
- 重新注册账号,并登录
最糟糕的情况是,整个ip被封,无论使用哪个账号都需要验证。这次还比较幸运,重新注册了一个网易账号,登录后,该账号就不再需要滑动验证。
那么问题来了,远程云服务器的IP怎么才能解封?云服务器没有界面,破解滑动验证码,成本太高;使用remote debug,乱码操作难度大,延迟太高,效率低下。
这里使用squid代理,在云服务器上安装squid,暴露8000端口,本机windows 通过java代码,chromedriver设置chrome的proxy地址为云服务器地址,端口8000,具体操作如下:
yum install squid
1.vi /etc/squid/squid.conf, 在结尾处追加:
dns_nameservers 8.8.8.8
http_port 8000
cache_mem 60 MB
2.注释掉默认的http_access deny all
创建squid交换目录:
cd /usr/sbin/
./squid -z
启动squid:
./squid
查看端口状态:
netstat -ntl
停止squid:
./squid -k shutdown
此时,squid已经安装并启动完毕,在windows本机,java代码里加入
ChromeOptions options = new ChromeOptions();
options.addArguments("--proxy-server=http://188.131.133.231:8000");
ChromeDriver driver = new ChromeDriver(options);
然后启动程序,打开chrome浏览器,此时打开百度,在搜索栏输入ip138,显示已经是云服务器的ip了,如此一来,本机chrome代理到云服务器上,可以手动输入滑动验证码,进行解锁。
我在这里试验了几种方式,老账号多次滑动验证通过,依然需要滑动验证,可能时间还不到。
通过新注册网易账号,登录,不需要验证码。通过。
总结
至此,考拉的验证和京东的验证都通过了,几个主要的难点及知识点
- chrome在linxu上界面乱码原因导致问题查找走了很大弯路
- 通过chrome remote debug定位linux chrome问题
- 通过squid代理,将云服务器ip映射到本地,本地手动滑动验证码解锁ip