Search code examples
pythonseleniumpyinstallerauto-py-to-exe

How to create a Python executable with Selenium and chromedriver?


python newbie here. I am trying to create an executable of my web scraping script so other users can access it, but I am having some problems. The script does include some inputs to work. I have tried using both auto-py-to-exe and pyinstaller, but after the exe is created in both, it doesn't seem to execute the script. For pyinstaller specifically I believe it has something to do with the .spec file, but I'm not sure.

I try to run this:

pyinstaller webscraper.spec webscraper.py

This is how my .spec file looks:

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None


a = Analysis(
    ['webscraper.py'],
    pathex=['C:\\Users\\myname\\Python\\webscraper'],
    binaries=[('C:\\Program Files (x86)\\chromedriver.exe', '***.\\selenium\\webdriver**')],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='webscraper',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='webscraper',
)

That seems to create the folder in \dist but running it doesn't do anything, as in nothing comes up for any inputs or anything.

When using auto-py-to-exe I am able to get where you can actually input the parameters, but then it fails opening chrome and just closes, so I can't see any errors that may be popping up.

I'm just not exactly sure what I am doing wrong here. Let me know if I need to include more info.

Code:

import os
import time
import math

import pandas as pd
import win32com.client as win32
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# load Excel file into python
excel_folder = input("Input excel folder path: ")
os.chdir(excel_folder)
excel_file = input("Input excel filename (with extension): ")
sheet_name = input("Input sheet name: ")
part_column = input("Input part number column name: ")
price_column = "Vendor Price"
batch_column = "Batch"
qty_column = "Vendor QTY"
total_column = "Total Price"
totalqty_column = "Total QTY"
xldata = pd.read_excel(excel_file, sheet_name=sheet_name)

# chrome driver path
s = Service(r"C:\Program Files (x86)\chromedriver.exe")
driver = webdriver.Chrome(service=s)

# get total row count (index=None for rows without labels)
df = pd.DataFrame(xldata, index=None)
rows = len(df.axes[0])

# close Excel if the file is open
xapp = win32.DispatchEx("Excel.Application")
xl = win32.GetActiveObject("Excel.Application")
for wb in xl.Workbooks:
    if os.path.dirname(wb.FullName) == excel_folder:
        wb.Close(True)
xapp.Quit()

# loop through all part numbers in worksheet
for row_curser in range(0, rows):
    xl_value1 = xldata[part_column][row_curser]
    xl_value2 = xldata[totalqty_column][row_curser]

    # go to part number webpage
    page = r"https://www.mcmaster.com/" + xl_value1 + r'/'
    driver.get(page)
    driver.maximize_window()

    # wait for page to load before locating elements
    time.sleep(1)

    # locate price
    price = driver.find_element(By.CLASS_NAME, "PrceTxt")

    # split price and UoM
    pt = price.text
    s = pt.split(' ')
    cost = s[0]
    batch = ' '.join(s[1:])
    qty = s[-1]

    # transform each to qty of 1
    if qty == 'Each':
        qty = 1
    else:
        qty = qty

    # get total price
    costsplit = cost.split('$')
    total = math.ceil(float(xl_value2) / float(qty)) * float(costsplit[1])

    # write prices to Excel
    df.at[row_curser, price_column] = cost
    df.at[row_curser, batch_column] = batch
    df.at[row_curser, qty_column] = qty
    df.at[row_curser, total_column] = total
    df.to_excel(excel_file, index=False)

# close web browser
driver.quit()

# open Excel file
xlapp = win32.DispatchEx("Excel.Application")
xlapp.WindowState = -4137
xlapp.Visible = 1
wb = xlapp.workbooks.open(excel_folder + "\\" + excel_file)

Solution

  • Thanks everyone. Seeing the error when running the exe in cmd per @m3nda, I was able to see that my chromedriver just needed to be updated in order for the exe to actually work, despite it working PyCharm.