无标题文章

---

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;

            """

```

你可能感兴趣的:(无标题文章)