SoFunction
Updated on 2025-04-14

FAQs and Solve Guides during PyInstaller Packaging Selenium-wire Process

Preface

Some time ago, I made an intranet development requirement, requiring the selenium program to be packaged into .exe and run it on win7 on the intranet. I searched online but found no related articles. Therefore, I shared the records of the pitfalls I stepped on during the process.

This article covers compatibility solutions for specific packaging operations, different modules and dependencies to ensure that they work properly both in packaging and runtime.

1. Background

In Python projects, when using third-party libraries (such as selenium, selenium-wire, mitmproxy, etc.), you encounter many dependencies and may cause runtime errors due to version compatibility issues between libraries. A commonly used packaging tool, PyInstaller, can package Python projects into a single executable file, but it can also cause various operational errors due to compatibility issues and path management. Therefore, this guide summarizes common problems and solutions during the packaging process to help developers complete the packaging and release of projects smoothly.

2. Overview of possible problems

There may be some problems when packaging selenium-wire in PyInstaller, as follows:

  • Dependency conflict: For example, the version conflict problem of pyOpenSSL and cryptography.
  • Path issue: such as not found or not loaded correctly at runtime.
  • Packaged file missing: Some files (such as .crt, .key, etc.) are not included when packaged, resulting in the runtime being unable to find.

3. PyInstaller packaging steps and parameter configuration

When using PyInstaller to package a Python project, you can generate an executable file through the following steps and commands:

pyinstaller --onefile --clean --hidden-import=<module> --name=<executable_name> <>

Detailed explanation of parameters:

  • --onefile: Package all files into a separate executable file.
  • --clean: Clean up the cache when packaged before and make sure to use the latest dependent version.
  • --hidden-import: Specifies the hidden modules included during packaging (dependencies that PyInstaller sometimes cannot automatically detect).
  • --name: Specifies the name of the executable file generated by the package.

For projects using .spec files, you can package them with the following command:

pyinstaller --clean <spec_file_name>.spec

4. Dependency version incompatibility issue

4.1 Compatibility issues between pyOpenSSL and cryptography

In PyInstaller-packaged projects, pyOpenSSL and cryptography are common dependencies. Due to version update issues, some versions of pyOpenSSL may not be compatible with newer versions of cryptography, resulting in missing properties such as X509_V_FLAG_NOTIFY_POLICY at runtime.

Common errors:

AttributeError: module 'lib' has no attribute 'X509_V_FLAG_NOTIFY_POLICY'

Solution:

1. Downgrade the cryptography version: It is recommended to downgrade to version 3.3.2 to ensure compatibility.

pip install cryptography==3.3.2

2. Downgrade pyOpenSSL version: Use version 20.0.1, which is more compatible with cryptography 3.3.2.

pip install pyOpenSSL==20.0.1

3. Upgrade all related dependencies: If using an older version is invalid, try upgrading selenium-wire, mitmproxy, pyOpenSSL, and cryptography to ensure that the dependencies are compatible with each other.

pip install --upgrade selenium-wire mitmproxy pyOpenSSL cryptography

4.2 Packaging issues

The path used by selenium must be specified explicitly in the system's PATH or by the code. However, after packaging into a single file, it may not be found normally and requires manual configuration.

5. Path problems and solutions

5.1 Include Files

Place the file in the project directory and include this file in the datas configuration of the .spec file to ensure that it is properly referenced after packaging.

Configuration example:

Add to datas in the .spec file:

datas=[
    ('&lt;absolute_path&gt;/', '.')  # Package to the root directory of the executable file]

Set relative paths in the code to reference the file, ensuring that the file can be correctly located in the packaged run environment.

from  import Service
import os
import sys

def resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return (sys._MEIPASS, relative_path)
    return (("."), relative_path)

chrome_driver_path = resource_path("")
service = Service(executable_path=chrome_driver_path)

6. Detailed solutions

During the packaging process, you may also encounter other common problems, such as file caching and packaging dependency file loss issues.

6.1 Clean cached files

Before packaging, make sure that PyInstaller does not use cached files by using the --clean parameter or manually deleting the build and dist folders:

pyinstaller --clean <spec_file_name>.spec

Or manually delete the build and dist folders:

rmdir /s /q build
rmdir /s /q dist

6.2 Configuring hiddenemports using .spec files

If PyInstaller does not automatically recognize all dependencies when packaged, you can explicitly specify the dependencies via the hiddendenimports parameter in the .spec file:

hiddenimports=['mitmproxy', 'seleniumwire', 'OpenSSL', 'cryptography'],

6.3 Include the certificate file in the package

The .crt and .key files used by certain dependencies (such as selenium-wire) also need to be manually included:

datas=[
    ('<absolute_path>/seleniumwire/', 'seleniumwire'),
    ('<absolute_path>/seleniumwire/', 'seleniumwire')
],

7. Debugging suggestions

Ensure that dependency versions are consistent: Use the same dependency version in development and packaging environments to prevent compatibility issues caused by inconsistent versions.

Using virtual environments: Each project configures a virtual environment separately to avoid conflicts caused by other dependencies in the global environment.

Step-by-step debugging: Before packaging, gradually test whether the dependency is running normally in the development environment. When encountering dependency issues, use compatible version combinations first.

8. Debugging dependency conflicts

Use the pip check command to check for dependency conflicts and get a list of dependencies via pip freeze to manage versions:

pip check  # Check for dependency conflictspip freeze &gt;   # Save the current dependency

Summarize

This guide summarizes common compatibility issues and solutions when using PyInstaller to package Python projects. The success rate of packaging can be significantly improved through the following steps:

Use compatible dependency versions, especially pyOpenSSL and cryptography.

Explicitly add the etc executable file to the .spec file.

Use sys._MEIPASS in your code to properly reference files in the packaged directory temporarily decompress.

Strictly following these steps can effectively avoid most packaging and runtime errors and ensure that the project runs stably in various environments.

This is the article about the common problems and solutions in the process of selenium-wire packaging of PyInstaller. For more information about PyInstaller packaging projects, please search for my previous articles or continue browsing the related articles below. I hope you will support me in the future!