title: Read/Write data from/to Excel using multiple threads/processes in parallel
body: <p>I'm working on a project which requires filling up a form (reading the input data from an excel sheet) and getting an output value (and save it to the excel sheet) when hitting the submit button. I have managed to automate this process with Python+Selenium but it takes quite some time to go over all rows of the xls file.</p>
  
  <p><em>Note: <code>XLUtils</code> is another python file with helper functions. I'm also using <code>openpyxl</code> and <code>xlrd</code> to read/write from the excel file</em></p>
  
  <p><strong>Here's the code (NO THREADS) on a high level:</strong></p>
  
  <pre><code>#Initial set-up
  url = "https://url.com"
  driver = webdriver.Chrome(options=options, executable_path=r'C:/chromedriver.exe')
  driver.get(url)
  driver.maximize_window()
  
  #Location of the input sheet
  path = "C:/Book1.xlsx"
  
  #Get number of rows from the excel input sheet
  rows = XLUtils.getRowCount()
  
  #Log into website
  XLUtils.login(driver)
  
  #Loop through all records from the input sheet
  for row_num in range(4, rows + 1):
      try:
          XLUtils.fill_out_form(driver, path, row_num)
      except:
          print("Element not found and test failed")
          continue
  
  #Log out and close Browser
  XLUtils.logout(driver)
  </code></pre>
  
  <p><strong>Here's an example of threading but it's quite simple as you would see below:</strong></p>
  
  <pre><code>def test_logic():
      url = "https://www.google.com"
      driver = webdriver.Chrome(options=options, executable_path=r'C:/chromedriver.exe')
      driver.get(url)
      driver.maximize_window()
      search_bar = driver.find_element_by_xpath("//input[@name='q']").send_keys("python threading")
      time.sleep(1)
      # driver.quit()
  
  num_browsers = 5   # Number of browsers to spawn
  thread_list = list()
  
  # Start test
  for i in range(num_browsers):
      t = threading.Thread(name='Test {}'.format(i), target=test_logic)
      t.start()
      time.sleep(1)
      print(t.name + ' started!')
      thread_list.append(t)
  
  # Wait for all threads to complete
  for thread in thread_list:
      thread.join()
  
  print('Test completed!')
  </code></pre>
  
  <p><strong>My question is</strong>: How can I merge the two codes to achieve my goal? Is it just a matter of wrapping the process I want to replicate in a function and then passing this function to the Threading code piece? If so, how would I manage to loop the entire xls file in batches of 5 and read/write each one from/to the resulting excel file.</p>
  
  <p>It's a tricky problem and I honestly haven't found a similar question around this so any help will be much appreciated.</p>