[PYTHON] Selenium running in 15 minutes

Selenium to understand in 10 minutes was very helpful, so I made a small sequel without permission.

Goal of this article

[Method 1 of "Selenium to understand in 10 minutes"](https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a#%E6%96%B9%E6%B3%951-docker-%E3%81%A7% According to E7% 92% B0% E5% A2% 83% E6% A7% 8B% E7% AF% 89), it takes time to build the environment by connecting to the Selenium Docker container that was created and moved earlier. You can easily mess with Selenium without having to. However, as it is, the Docker container will continue to work even after using the Selenium script, and you will have to quit it yourself.

In this article, we will automate the process of stopping and removing the Docker container after running the script. So ** It's a lie that this article is a Selenium article. ** Title fraud. sorry.

This article will show you a nice way to work with Docker container with Docker SDK for Python based on Selenium. ..

TL;DR First, install Docker SDK for Python.

pip install docker
import docker
import time
from selenium import webdriver
from contextlib import contextmanager

SELENIUM_IMAGE = 'selenium/standalone-chrome:3.141.59-xenon'


@contextmanager
def selenium_container():
    client = docker.from_env()
    try:
        selenium_image = client.images.get(SELENIUM_IMAGE)
    except docker.errors.ImageNotFound:
        selenium_image = client.images.pull(SELENIUM_IMAGE)

    container = client.containers.run(
        selenium_image, detach=True, remove=True,
        ports={4444: 4444}, shm_size='2g')
    try:
        while b'Selenium Server is up' not in container.logs():
            time.sleep(0.1)
        yield container
    finally:
        container.kill()


@contextmanager
def selenium_driver():
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    driver = webdriver.Remote(
        command_executor='http://localhost:4444/wd/hub',
        desired_capabilities=options.to_capabilities(),
        options=options,
    )
    try:
        yield driver
    finally:
        driver.quit()


def test():
    with selenium_container(), selenium_driver() as driver:
        driver.get('https://qiita.com')
        print(driver.current_url)


if __name__ == '__main__':
    test()

Commentary

contextmanager

@contextmanager
def selenium_container():

I used contextlib.contextmanager to terminate container successfully even if an error occurs. The same is true for webdriver.

Get Docker image

    client = docker.from_env()
    try:
        selenium_image = client.images.get(SELENIUM_IMAGE)
    except docker.errors.ImageNotFound:
        selenium_image = client.images.pull(SELENIUM_IMAGE)

First, get the Docker image of Selenium. If you haven't pulled it yet, pull it first.

docker run

    container = client.containers.run(
        selenium_image, detach=True, remove=True,
        ports={4444: 4444}, shm_size='2g')

This is equivalent to docker run -d -p 4444: 4444 --shm-size = 2g selenium / standalone-chrome: 3.141.59-xenon.

docker kill

    try:
        while b'Selenium Server is up' not in container.logs():
            time.sleep(0.1)
        yield container
    finally:
        container.kill()

Since we're passing detach = True,client.containers.run ()moves to the next step as soon as we launch Docker container. Therefore, Webdriver is not yet ready at this stage. First you have to wait until it's ready. When the preparation is completed, the Docker container log will output 06: 53: 00.628 INFO [SeleniumServer.boot] --Selenium Server is up and running on port 4444, etc., so turn the while loop until you see this output. Wait [^ 1].

[^ 1]: Docker SDK for Python documentation has logs () It is written that returns str, but please note that it returns bytes for some reason at the time of writing the article.

Yield container when ready. This yielded container can be referenced as with selenium_container () as container:. The processing of selenium_driver is paused when the container is yielded and waits until it exits the with block. If the process completes or an error occurs inside the with block and exits the with block, the selenium_driver will start again and thecontainer.kill ()of the finally block will be killed. I will do it.

Summary

Now you don't have to worry about forgetting to quit Docker container or Webdriver. Have a good Selenium life!

Recommended Posts

Selenium running in 15 minutes
Learn Pandas in 10 minutes
Scraping with selenium in Python
Scraping with Selenium in Python
Wrapper running Hadoop in Python
Start in 5 minutes GIMP Python-Fu
Scraping with Selenium in Python (Basic)
Fixed Apscheduler running twice in Flask
Let's experience BERT in about 30 minutes.
Scraping with Beautiful Soup in 10 minutes
Write selenium test code in python
I tried running GAN in Colaboratory
Make matplotlib Japanese compatible in 3 minutes
Deploy Django in 3 minutes using docker-compose
[Understanding in 3 minutes] The beginning of Linux
[Python] Pandas to fully understand in 10 minutes
I can't get the element in Selenium!
The basics of running NoxPlayer in Python
Django Foreign Key Tutorial Ends in 10 Minutes
Screenshots of Megalodon in selenium and Chrome.
Get Cloud Logging available in Python in 10 minutes
Freeze with send_keys of file selection when running Selenium WebDriver in Python [PhantomJS]