基于selenium的分布式爬虫-微浏览器
文档:https://github.com/SeleniumHQ/docker-selenium
1.背景
在无法使用的正常的接口请求数据时,我们想到最多的就是使用了浏览器进行抓取
2.正常流程
windows下使用selenium找标签,定位标签,最终在windows下完成初步代码测试
selenium-->定位标签-->执行执行相应的浏览器操作-->测试(这一切测试过程是可见)
3.问题
1.我们如何将写好的代码放到Linux系统,长期的运行呢?
2.是否在windows下能够正常运行的代码,放到Linux下,就可以正常跑呢?
答案是:
1.我们可以将代码放到Linux下长期跑,并且我们做到分布式,这一点对于大数据非常有用!
2.windows下的代码也许可以跑,放到Linux下不一定正确,大部分人Linux的浏览器估计想到的都是Phantomjs,这种浏览器,其实有很多bug,比如:
a) 如果你有登录操作,他不一定能处理登陆的弹框
b) Phantomjs的渲染方式与正常浏览器渲染方式相差很大
c) Phantomjs最大的作用在于执行js
所以你如果遇到比较复杂的网站,Phantomjs不一定能跑通带代码
4.解决办法
使用docker的selenium浏览器
好处:
a) Linux下可以运行
b) 支持远程连接浏览器
c) 便于搭建分布式
d) 无需在关心无界面与有界面的区别
e) 可以使用市场上最火的firefox,chrome,sarifi等,灵活性非常强
5.使用样例
1.拉取官方镜像
[[email protected] ~]# docker pull selenium/standalone-chrome
2.运行浏览器容器
[[email protected] ~]# docker run -d -p 4444:4444 selenium/standalone-chrome
or
[[email protected] ~]# docker run -d -p 4444:4444 -v /dev/shm:/dev/shm selenium/standalone-chrome
3.测试用例
import multiprocessing
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def test():
driver = webdriver.Remote( command_executor="http://127.0.0.1:4444/wd/hub", desired_capabilities=DesiredCapabilities.CHROME )
driver.get("http://www.baidu.com")
print(driver.title)
driver.close()
def main():
pool = multiprocessing.Pool(10)
for one in range(100):
pool.apply_async(test)
pool.close()
pool.join()
if __name__ == '__main__':
main()
4.运行结果
...
百度一下,你就知道
百度一下,你就知道
百度一下,你就知道
...
6.如何搭建分布式
官方中给出selenium/hub这个镜像,该镜像的作用类似于中央处理器,可以管理每一个浏览器节点
https://github.com/SeleniumHQ/docker-selenium文档中提到selenium grid给我们提供了两个东西。一个叫hub,一个叫node,hub被称为总控节点,node称之为节点
结构如下 :
1.拉取官方镜像hub
[[email protected] ~]# docker pull selenium/node-chrome
[[email protected] ~]# docker pull selenium/hub
[[email protected] ~]# docker pull selenium/node-firefox
2.启动镜像
[[email protected] ~]# docker run -p 5555:4444 -d --name selenium_hub selenium/hub
[[email protected] ~]# docker run -P -d --link selenium_hub:hub selenium/node-firefox
3.验证
浏览器中输入http://xx.xx.xx.xx:5555/grid/console
你会发现有一个火狐节点被注册管理了
4.测试用例
#coding=utf-8
from selenium import webdriver
firefox_capabilities ={
"browserName": "firefox",
"version": "50.0",#注意版本号一定要写对
"platform": "ANY",
"javascriptEnabled": True,
"marionette": True,
}
browser=webdriver.Remote("http://192.168.99.100:5555/wd/hub",desired_capabilities=firefox_capabilities) #注意端口号5555是我们上文中映射的宿主机端口号
browser.get("http://www.baidu.com")
print(browser.title)
browser.close()
问题:
再次在IDE运行下这个脚本,发现一直处于阻塞状态也不报错,得不到hub远程的执行信息
我认为这种分布式一般只是针对专用于测试用的,并非爬虫分布式
5.另外思路
利用单节点docker,我们分别部署后,对每次请求浏览器实例时可以随机分配,这种分布式既好搭,并且不会消耗太多内存(经测试)
利用k8s搭建真正的分布式浏览器,搭建方法:https://blog.****.net/xzpdxz/article/details/89179316