基于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.拉取官方镜像

[root@i ~]# docker pull selenium/standalone-chrome

2.运行浏览器容器

[root@i ~]# docker run -d -p 4444:4444 selenium/standalone-chrome
or
[root@i ~]# 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

[root@i ~]# docker pull selenium/node-chrome
[root@i ~]# docker pull selenium/hub
[root@i ~]# docker pull selenium/node-firefox

2.启动镜像

[root@i ~]# docker run -p 5555:4444 -d --name selenium_hub  selenium/hub
[root@i ~]# 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.csdn.net/xzpdxz/article/details/89179316

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章