有了无头浏览器,我们就能做包括但不限于以下事情:
- 对网页进行截图保存为图片或 pdf。
- 抓取单页应用(SPA)执行并渲染(解决传统 HTTP 爬虫抓取单页应用难以处理异步请求的问题)。
- 做表单的自动提交、UI的自动化测试、模拟键盘输入等。
- 用浏览器自带的一些调试工具和性能分析工具帮助我们分析问题。
- 在最新的无头浏览器环境里做测试、使用最新浏览器特性。
- 写爬虫做你想做的事情。
无头浏览器很多,包括但不限于:
- PhantomJS, 基于 Webkit
- SlimerJS, 基于 Gecko
- HtmlUnit, 基于 Rhnio
- TrifleJS, 基于 Trident
- Splash, 基于 Webkit
这里我们简单来说,在selenium中使用无头浏览器。
PhantomJS
PhantomJS是一个无界面的、可脚本编程的WebKit浏览器引擎,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。
- PhantomJS是一个基于webkit内核、无界面的浏览器,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现;
- PhantomJS提供Javascript API接口,可以通过编写JS程序直接与webkit内核交互;
- PhantomJS的应用:无需浏览器的 Web 测试、网页截屏、页面访问自动化、网络监测。
安装
下载安装
根据自己的系统平台,下载相应的包,我这里是Windows 64位系统,所以,我选择下载windows版本的,phantomjs-2.1.1版本下载地址:
https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip
在压缩包解压后,将其中的bin目录添加到环境变量中:
测试
import time
from selenium import webdriver
path = r'C:python36Scriptsphantomjs-2.1.1-windowsinphantomjs.exe'
driver = webdriver.PhantomJS(executable_path=path)
driver.implicitly_wait(10)
driver.get('https://www.baidu.com')
print(driver.title) # 百度一下,你就知道
time.sleep(1)
driver.quit()
但是有时候,虽然添加了path,但还是不好用,会报这个错误:
selenium.common.exceptions.WebDriverException: Message: 'phantomjs' executable needs to be in PATH.
解决办法是如我上例中那样,执行上驱动的path就好了。
模拟登陆示例
我们现在来一个示例,就是模拟登陆网站,在输入用户名、密码和验证码都错误的情况下,网站会给出一个提示信息,我们根据提示信息来判断,如果有提示信心,那么说明登录失败,我们就截图记录下有提示信息的界面。
import time
from selenium import webdriver
path = r'C:python36Scriptsphantomjs-2.1.1-windowsinphantomjs.exe'
driver = webdriver.PhantomJS(executable_path=path)
driver.implicitly_wait(10)
try:
driver.get('https://pythonav.com/login/')
driver.find_element_by_id('id_username').send_keys('123')
driver.find_element_by_id('id_password').send_keys('123')
driver.find_element_by_id('id_code').send_keys('123')
driver.find_element_by_xpath('//*[@id="fm"]/div[5]/div/input').click()
time.sleep(1)
result = driver.find_element_by_xpath('//*[@id="fm"]/div[1]/span').text
if result: # 如果提示信息有值,说明登录失败,需要截图
driver.save_screenshot('./error.png')
else:
print('登录成功......')
except Exception as e:
print(e)
driver.save_screenshot('./error.png')
finally:
time.sleep(3)
driver.quit()
当脚本执行完毕后,在脚本的同级目录,会有一个error.png
图片:
OK,完美!
谷歌无头浏览器
因为phantomjs暂停开发,我们选择使用(并且优先推荐)谷歌的无头浏览器。
更多关于phantomjs暂停开发信息,参见:https://github.com/ariya/phantomjs/issues/15344
什么是无头浏览器(headless browser)?
无头浏览器是指可以在图形界面情况下运行的浏览器。我们可以通过编程来控制无头浏览器自动执行各种任务,比如做测试,给网页截屏等。
为什么叫“无头”浏览器?
“无头”这个词来源于最初的“无头计算机(Headless computer)”。维基百科关于的“无头计算机”词条:
无头系统(headless system)是指已配置为无须显示器(即“头”)、键盘和鼠标操作的计算机系统或设备。无头系统通常通过网络连接控制,但也有部分无头系统的设备需要通过RS-232串行连接进行设备的管理。服务器通常采用无头模式以降低运作成本。
配置无头的相关参数
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建一个参数对象,用来控制chrome以无界面模式打开
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 创建浏览器对象
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.implicitly_wait(10)
# 访问URL
driver.get('https://www.baidu.com')
print(driver.title) # 百度一下,你就知道
time.sleep(1)
driver.quit()
模拟登录示例
再来一个示例,跟phantomjs一样的模拟登陆的示例:
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建一个参数对象,用来控制chrome以无界面模式打开
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 创建浏览器对象
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.implicitly_wait(10)
try:
driver.get('https://pythonav.com/login/')
driver.find_element_by_id('id_username').send_keys('123')
driver.find_element_by_id('id_password').send_keys('123')
driver.find_element_by_id('id_code').send_keys('123')
driver.find_element_by_xpath('//*[@id="fm"]/div[5]/div/input').click()
time.sleep(1)
result = driver.find_element_by_xpath('//*[@id="fm"]/div[1]/span').text
if result: # 如果提示信息有值,说明登录失败,需要截图
driver.save_screenshot('./error.png')
else:
print('登录成功......')
except Exception as e:
print(e)
driver.save_screenshot('./error.png')
finally:
time.sleep(3)
driver.quit()
除了无头,其他用法没有变化。