用到的工具有chromedriver,pywin32和selenium。chromedriver安装配置过程自行百度,需要注意的是chromedriver和chrome的版本号需要一一对应,否则会出现不必要的报错。
1、以新浪的一条新闻网址为例
news_url = "http://news.youth.cn/sz/201812/t20181218_11817816.htm"
driver.get(news_url)
2、需要明确的是,我们现在要保存的是一个完整的网页,不是单独的html文档,还要包括JavaScript和CSS等内容,换句话说,也就是离线网页,断网之后还可以正常打开。经过多次采坑之后发现chrome可以直接保存为一个单独的mhtml文档,但是chrome是默认关闭状态,这时候我们就需要在webdriver中打开这个设置。
options = webdriver.ChromeOptions()
options.add_argument('--save-page-as-mhtml')
driver = webdriver.Chrome(chrome_options=options)
3、接下来就要开始保存网页了,通常保存一个网页我们需要进行Ctrl+A,Ctrl+S,然后Enter三步操作,这些操作我们可以通过Actionchains来做,踩坑现场发现这个selenium的键盘操作是直接发送到webdriver的界面,而不是控制弹出浮动窗口(右键窗口)。多次尝试之后,发现pywin32的键盘模拟控制可以实现,上码。
win32api.keybd_event(17, 0, 0, 0) # 按下ctrl
win32api.keybd_event(65, 0, 0, 0) # 按下a
win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放a
win32api.keybd_event(83, 0, 0, 0) # 按下s
win32api.keybd_event(83, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放s
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放ctrl
win32api.keybd_event(13, 0, 0, 0) # 按下enter
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放enter
这次python自动化测试的尝试比较满意,之前看到网上有很多博客对于离线网络的保存都只是实现了html文档的保存(断网后无法看到图片),而对于离线网页更好的保存为单个mhtml文档,没有发现很好实现的。更值得一提的是,selenium自动化测试是完全模拟浏览器,没有任何一个网站会去屏蔽一个浏览器的访问(如果有,请看上一句)。
在踩坑的路上走了不少弯路,最终还是在overflow上大佬的回答中找到了灵感,以下贴出来全部代码供大家才考,希望学习爬虫的朋友少走些弯路。
from selenium import webdriver
import time
import win32api
import win32con
# 测试网址
news_url = "http://news.youth.cn/sz/201812/t20181218_11817816.htm"
# 打开另存为mhtml功能
options = webdriver.ChromeOptions()
options.add_argument('--save-page-as-mhtml')
# 设置chromedriver,并打开webdriver
driver = webdriver.Chrome(chrome_options=options)
driver.get(news_url)
# 模拟键盘操作
win32api.keybd_event(17, 0, 0, 0) # 按下ctrl
win32api.keybd_event(65, 0, 0, 0) # 按下a
win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放a
win32api.keybd_event(83, 0, 0, 0) # 按下s
win32api.keybd_event(83, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放s
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放ctrl
win32api.keybd_event(13, 0, 0, 0) # 按下enter
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放enter
# 预估下载时间,后期根据实际网速调整
time.sleep(5)
# 关闭webdriver
driver.close()