Python selenium - package your automation script into an exe

1. Environment

  1. First prepare the environment, a 32-bit virtual machine (64-bit py2exe does not allow the program to be packaged into an exe file), with the Python version required for your script execution and all the third-party libraries (make sure that this machine can execute your script), install the py2exe package corresponding to your Python version.

  2. Want to package the py script, the following is a simple example of opening chrome and visiting the gray- blue blogblog.py :

# -*- coding: utf-8 -*-

from selenium import webdriver
import time

driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('http://blog.csdn.net/huilan_same')
time.sleep(5)
driver.quit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Now let's type this little script into an exe

2. setup

We create another packaging scriptsetup.py

# -*- coding: utf-8 -*-

from distutils.core import setup
import py2exe, sys
sys.argv.append('py2exe')

options = {"py2exe": {
    "compressed": 1,  # 压缩
    "optimize": 2,
    "bundle_files": 1,  # 所有文件打包成一个exe文件
}}

setup(
    console=[{'script': "blog.py", "icon_resources": [(1, "robot.ico")]}],
    options=options,
    zipfile=None
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

I added an icon to the program, and the icon file robot.ico is also placed in the same directory. Then we execute this script, and we can see that two folders, build and dist, are created after a series of packaging operations in cmd. What we are useful is distonly the blog.exefile in (the same name as the py script), and there will be another one w9xpopen.exe, which is used by the win9x system, which is meaningless.

folder directory

Note: The blogger here will no longer explain the usage of py2exe in detail. If you are interested in the content of the script, you can learn about Baidu by yourself.

Take it out blog.exe, put it in the same directory chromedriver.exe(note the version), double-click to execute

implement

Now, you don't have to do the environment every time.

3. Execute firefox

Above I deliberately chose chrome as an example instead of firefox, because firefox is special, just like the above

driver = webdriver.Chrome(executable_path='chromedriver.exe')
  • 1
  • 2

change to

driver = webdriver.Firefox()
  • 1
  • 2

If the package is successful, the following error will be reported when executing:

execution error

Less typing webdriver_pref.jsonfiles , I have seen a solution on stackoverflow is to modify the packaging parameters and copy all the resource files, which will be a bloated folder after typing, and later bloggers will not use this method. .

So what should I do? Seeing that the error is missing a json file, can we write this json file directly into our script? So the blogger looked at the source code and found that it was mainly usedFirefoxProfile by the class . In this case, we will __init__()Inherit and override this method:

References in source code

At the same time, we also found another reference webdriver.xpi, this file is equivalent to the firefox driver in selenium2, and it will be imported in the form of a plug-in when starting firefox. So the add_extension()method also needs to be rewritten.

Finally, the code is as follows:

# -*- coding: utf-8 -*-

from selenium import webdriver
import time
# 下面几个包都是FirefoxProfile需要的
import copy
import json
import tempfile
import shutil
import os

# 这里将该json文件里的内容都放到了我们的脚本里,你也可以放到另一个py文件中import进来
WEBDRIVER_PREFERENCES = """
{
  "frozen": {
    "app.update.auto": false,
    "app.update.enabled": false,
    "browser.displayedE10SNotice": 4,
    "browser.download.manager.showWhenStarting": false,
    "browser.EULA.override": true,
    "browser.EULA.3.accepted": true,
    "browser.link.open_external": 2,
    "browser.link.open_newwindow": 2,
    "browser.offline": false,
    "browser.reader.detectedFirstArticle": true,
    "browser.safebrowsing.enabled": false,
    "browser.safebrowsing.malware.enabled": false,
    "browser.search.update": false,
    "browser.selfsupport.url" : "",
    "browser.sessionstore.resume_from_crash": false,
    "browser.shell.checkDefaultBrowser": false,
    "browser.tabs.warnOnClose": false,
    "browser.tabs.warnOnOpen": false,
    "datareporting.healthreport.service.enabled": false,
    "datareporting.healthreport.uploadEnabled": false,
    "datareporting.healthreport.service.firstRun": false,
    "datareporting.healthreport.logging.consoleEnabled": false,
    "datareporting.policy.dataSubmissionEnabled": false,
    "datareporting.policy.dataSubmissionPolicyAccepted": false,
    "devtools.errorconsole.enabled": true,
    "dom.disable_open_during_load": false,
    "extensions.autoDisableScopes": 10,
    "extensions.blocklist.enabled": false,
    "extensions.checkCompatibility.nightly": false,
    "extensions.logging.enabled": true,
    "extensions.update.enabled": false,
    "extensions.update.notifyUser": false,
    "javascript.enabled": true,
    "network.manage-offline-status": false,
    "network.http.phishy-userpass-length": 255,
    "offline-apps.allow_by_default": true,
    "prompts.tab_modal.enabled": false,
    "security.csp.enable": false,
    "security.fileuri.origin_policy": 3,
    "security.fileuri.strict_origin_policy": false,
    "security.warn_entering_secure": false,
    "security.warn_entering_secure.show_once": false,
    "security.warn_entering_weak": false,
    "security.warn_entering_weak.show_once": false,
    "security.warn_leaving_secure": false,
    "security.warn_leaving_secure.show_once": false,
    "security.warn_submit_insecure": false,
    "security.warn_viewing_mixed": false,
    "security.warn_viewing_mixed.show_once": false,
    "signon.rememberSignons": false,
    "toolkit.networkmanager.disable": true,
    "toolkit.telemetry.prompted": 2,
    "toolkit.telemetry.enabled": false,
    "toolkit.telemetry.rejected": true,
    "xpinstall.signatures.required": false,
    "xpinstall.whitelist.required": false
  },
  "mutable": {
    "browser.dom.window.dump.enabled": true,
    "browser.laterrun.enabled": false,
    "browser.newtab.url": "about:blank",
    "browser.newtabpage.enabled": false,
    "browser.startup.page": 0,
    "browser.startup.homepage": "about:blank",
    "browser.usedOnWindows10.introURL": "about:blank",
    "dom.max_chrome_script_run_time": 30,
    "dom.max_script_run_time": 30,
    "dom.report_all_js_exceptions": true,
    "javascript.options.showInConsole": true,
    "network.http.max-connections-per-server": 10,
    "startup.homepage_welcome_url": "about:blank",
    "startup.homepage_welcome_url.additional": "about:blank",
    "webdriver_accept_untrusted_certs": true,
    "webdriver_assume_untrusted_issuer": true
  }
}
"""


class FirefoxProfile(webdriver.FirefoxProfile):
    """ Rewrite FirefoxProfile, to avoid 'No such file ... webdriver.xpi/pref.json' exception"""
    def __init__(self, profile_directory=None):
        if not FirefoxProfile.DEFAULT_PREFERENCES:
            FirefoxProfile.DEFAULT_PREFERENCES = json.loads(WEBDRIVER_PREFERENCES)

        self.default_preferences = copy.deepcopy(
            FirefoxProfile.DEFAULT_PREFERENCES['mutable'])
        self.native_events_enabled = True
        self.profile_dir = profile_directory
        self.tempfolder = None
        if self.profile_dir is None:
            self.profile_dir = self._create_tempfolder()
        else:
            self.tempfolder = tempfile.mkdtemp()
            newprof = os.path.join(self.tempfolder, "webdriver-py-profilecopy")
            shutil.copytree(self.profile_dir, newprof,
                            ignore=shutil.ignore_patterns("parent.lock", "lock", ".parentlock"))
            self.profile_dir = newprof
            self._read_existing_userjs(os.path.join(self.profile_dir, "user.js"))
        self.extensionsDir = os.path.join(self.profile_dir, "extensions")
        self.userPrefs = os.path.join(self.profile_dir, "user.js")

    def update_preferences(self):
        for key, value in self.DEFAULT_PREFERENCES['frozen'].items():
            self.default_preferences[key] = value
        self._write_user_prefs(self.default_preferences)

    def add_extension(self, extension=os.path.abspath('webdriver.xpi')):
        self._install_extension(extension)


# driver = webdriver.Chrome(executable_path='chromedriver.exe')
profile = FirefoxProfile()  # 这里需要实例化并用该profile启动firefox
driver = webdriver.Firefox(firefox_profile=profile)
driver.get('http://blog.csdn.net/huilan_same')
time.sleep(5)
driver.quit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132

We pack it again, webdriver.xpicopy it out to the program directory, double-click it again to execute blog.exe, bingo, it can be executed.

4. Extension

At this time, your script can run in different win environments. If you add the yaml file as the configuration file, excel as the data file, and add the log, if you have time, you can also add the gui, you can make a configurable The web page automatic form filling program came out, do it yourself.

Notice:

All the above examples are of Python2.7 + selenium 2.53 version, chrome only needs to match the chromedriver version; if you use selenium3.x, for firefox48 and above, you need to use geckdriver, and you need to look at the source code accordingly. Change it.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324735981&siteId=291194637