写好了Python selenium脚本,到其余机器上运行,还得要在其余机器上也装一套Python的环境,尤为在你用了一些第三方库的时候,甚至还要顾及操做系统是32位仍是64位,是否是很坑,若是能打成一个exe就行了,不论32位仍是64位,只要拷过去,安装合适版本的浏览器就好了。今天博主就带你将你的py脚本打包成一个exejavascript
1. 环境
首先准备下环境,一台32位虚拟机(64位的py2exe不容许将程序打包成1个exe文件),装有你脚本执行须要的Python版本以及全部的三方库(确保在这台机器上可以执行你的脚本),安装跟你Python版本对应的py2exe包。html
想要打包的py脚本,下面是一个简单的打开chrome并访问灰蓝博客的例子 blog.py:java
# -*- 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()
如今咱们就把这个小脚本打成一个exepython
2. setup
咱们建立另外一个打包脚本 setup.py web
# -*- 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
)
我给程序加了图标,图标文件robot.ico也放在同一目录下,而后咱们执行这个脚本,可以看到cmd中一系列的打包操做后建立了两个文件夹build和dist,其中,真正对咱们有用的只是 dist 中的 blog.exe 文件(与py脚本同名),还会有一个 w9xpopen.exe ,这个是用于win9x系统使用的,没有意义。chrome
注:这里博主再也不详细讲解py2exe的用法,关于脚本内容感兴趣能够自行百度相关知识shell
取出 blog.exe ,同目录下放 chromedriver.exe (注意版本),双击执行便可json
这下,不用每次都搞环境了。浏览器
3. 执行firefox
上面我故意选了chrome做为例子,而非firefox,是因为firefox比较特殊,像上面同样只是把session
driver = webdriver.Chrome(executable_path='chromedriver.exe')
改为
driver = webdriver.Firefox()
的话,打包成功但执行时会报以下错误:
少打了 webdriver_pref.json 文件,曾在stackoverflow上看到过一种解决办法是修改打包参数并把resource文件都copy过来,这种打出来以后会是一个臃肿的文件夹,后来博主便不用这种办法了。
那怎么办,看报错是少了一个json文件,那么可否把这个json文件直接写进咱们的脚本里呢,因此博主便去看源码,发现主要是FirefoxProfile类的 __init__()用到了,既然如此,咱们便继承过来并重写了此方法便可:
同时,咱们还发现另外一个引用 webdriver.xpi ,此文件在selenium2中至关于firefox的驱动,在启动firefox时会以插件的形式导入。因此add_extension()方法也须要重写。
最后,代码以下:
# -*- 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()
咱们再次打包,把 webdriver.xpi拷贝出来到程序目录下,再次双击执行blog.exe,bingo,能够执行了。
4. 扩展
这时你的脚本就能够在不一样的win环境下跑了,若是加上yaml文件做为配置文件、excel做为数据文件、并加上日志,若是有时间还能够加上gui,就能够作一个可配置的网页自动填表程序出来了,本身动手吧。
注意:
以上全部示例均为Python2.7 + selenium 2.53版本的,chrome只要跟chromedriver版本匹配便可;若是你用的selenium3.x,对于firefox48及以上的版本,须要用到geckdriver,具体的本身看源码作相应改动吧。
更多关于python selenium的文章,请关注个人CSDN专栏:
最后,博主最近新建了一个QQ群,用于Python Selenium的技术交流,专一于Python+Selenium的技术交流与分享,感兴趣的同窗能够加群(455478219),也可直接点击下面的图片加群:
欢迎来跟博主讨论Python Selenium有关的问题。