---
title: 使用Chrome来做一张网页长截图
tag: code
date: 2018-07-07
---
![chrome-headless](/img/chrome-headless.jpg)
***
遇见一篇有意思的文章,或者是在购物时发现了好东西,需要分享。
不想发送链接,也许搞一个长截图是个很好的选择。
# Selenium
Selenium是一种自动化测试工具,它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。Selenium支持多种语言开发,比如 Java,C,Ruby,Python等等。
### 使用pip3安装selenium依赖
```sh
$ pip3 install selenium
```
### 获取chrome-driver
在淘宝npm镜像中可以找到Chrome版本对应的驱动: http://npm.taobao.org/mirrors/chromedriver/
# 初始化浏览器
```Python
def init_browser():
chrome_options = Options()
# --headless参数表示,Chrome将不会有一个可视化的图形界面
# chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--disable-web-security")
# 以iPhone 6的屏幕宽度作为基准
mobile_emulation = { "deviceName": "iPhone 6" }
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
return webdriver.Chrome("./chromedriver",
chrome_options=chrome_options)
browser = inti_browser()
```
# 调用webdriver提供的API, 获取网页基本信息
```python
url = "https://code.evink.me"
# 设置页面渲染超时
browser.set_page_load_timeout(30)
# 设置脚本执行超时
browser.set_script_timeout(100)
# 需要截屏的网页
browser.get(url)
# 给浏览器设置一个默认的初始宽高(非必要)
browser.set_window_size(375, 1000)
```
Chrome在iPhone 6的模拟环境下进行网页渲染,其宽是一定的,所以可以通过调用运行于webdriver内部的javascript代码,获得我们想要的内容。
webdrive提供了丰富的接口供我们全方位操控这个小小的浏览器。
```python
# browser是我们刚刚初始化的浏览器实例
body_height = browser.body.get_attribute("clientHeight")
```
或者,这里还有一个更加可操作的方法,直接在webdriver里跑js代码。Selenium提供了execute_script(str)接口,可以让用户通过熟悉的方式,得到自己想要的。
```python
# browser是我们刚刚初始化的浏览器实例
body_height = browser.execute_script(get_script("body_height")))
# get_script(str) -> str
def get_script(_type):
if _type == "body_height":
return """
// get body_height
return document.getElementsByTagName("body")[0].clientHeight;
"""
```
# 滚屏截图
webdriver提供了一个保存当前浏览器窗口截图的接口save_screenshot(path)
我们只需要让网页沿着一个预设定的高度滚动就好。
这里,这个高度是667(基于我们以iPhone 6的虚拟环境初始化的浏览器)。设定大于667的高度,每次也并不会截取到更多的页面内容,而小于667的高度,会让你最后进行图片处理的时候非常头疼。
```python
paging_list = []
def take_screenshot():
# loop_times由网页高度和单屏高度计算而来
for i in range(loop_times):
browser.execute_script(get_script("scroll_window") % i)
if i + 1 == loop_times:
scroll_y = browser.execute_script(get_script("scroll_y"))
print("scroll_y:", scroll_y)
self.screenshot_remainder = i * 667 - scroll_y
# 截取屏幕
path = "%s/%s_%s.png"%(self.dir_path, self.filename, i)
browser.save_screenshot(path)
paging_list.append(path)
return paging_list
def get_script(_type):
if _type == "scroll_window":
return """
// 滚动的次数
var m = %s;
// 屏幕range
var begin = 0;
var end = 667;
// 滚屏
window.scrollTo(begin, end * m);
"""
if _type == "scroll_y":
return """
return window.scrollY;
"""
```