9

I want to open and login 5 tabs concurrently without delay in between in tabs. I have tried:

import threading
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def openurl(threadId):
    print(threading.currentThread().getName(),' Thread')
    url = ('https://www.facebook.com/')
    print(url)
    driver.execute_script("window.open('{0}')".format(url))
    #driver.title(threadId)
    time.sleep(0.1)

    driver.set_window_size(920, 680)
    driver.find_element(By.ID, "email").send_keys("xx")
    driver.find_element(By.ID, "pass").send_keys("yy")
    driver.find_element(By.ID, "loginbutton").click()


if __name__=='__main__':
    driver = webdriver.Chrome()
    windows_before  = driver.current_window_handle
    for i in range(5):
        t1 = threading.Thread(name=i,target=openurl, args=(i,))
        t1.start()
        t1.join()

but it is throwing:

Traceback (most recent call last): File "C:\Users\1024983\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "C:\Users\1024983\AppData\Local\Programs\Python\Python37\fb-thread.py", line 30, in openurl driver.find_element(By.ID, "email").send_keys("xx") File raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="email"]"} (Session info: chrome=78.0.3904.108)

If I increased sleep time, there is a delay in-between tabs. I tried to navigate using driver.title but my case title is same for all tabs.

12
  • 1
    You can use wait for object to appear to be sure on the object appearance in a given time limit: stackoverflow.com/a/20903328/12422518 Commented Dec 18, 2019 at 7:54
  • 1
    This might be helpful Commented Dec 18, 2019 at 8:01
  • can you help me to create "instances of webdriver" @Shijith Commented Dec 18, 2019 at 8:45
  • always put full error message (starting at word "Traceback") in question (not comment) as text (not screenshot). There are other useful information. Commented Dec 18, 2019 at 8:48
  • this code driver = webdriver.Chrome() creates instance of webdriver Commented Dec 18, 2019 at 8:51

1 Answer 1

6

It is example uses threads to run separated browsers which fill form and set True in list buttons to inform that login button is ready to click. When all browsers set True in list buttons then all of them click buttons.

It seems that it runs amost a the same time - maybe only system has some to makes so many connections at the same time.

I used list buttons to synchronize all threads. Every thread get number to have own place in list. I don't use append(True) because I'm not sure it can be thread-safe.

import time
from selenium import webdriver
from threading import Thread

def func(number):
    driver = webdriver.Chrome()
    #driver.set_window_size(920, 680)
    driver.get(url)

    driver.find_element_by_id("email").send_keys("xx")
    driver.find_element_by_id("pass").send_keys("yy")
    b = driver.find_element_by_id("loginbutton")

    buttons[number] = True
    print(buttons)

    # wait for other buttons
    while not all(buttons):
        pass

    print('click', number)
    b.click()

# ---

url = 'https://www.facebook.com/'

number_of_threads = 5

#buttons = [False * number_of_threads] # create place 
buttons = []

threads = []

for number in range(number_of_threads):
    t = Thread(target=func, args=(number,)) # get number for place in list `buttons`
    t.start()
    threads.append(t)
    buttons.append(False) # create place 

for t in threads:
    t.join()

EDIT: The same with threading.Barrier(5) and 5 threads will have to run barrier.wait() to move forward.

import time
from selenium import webdriver
from threading import Thread, Barrier

def func(barrier):

    driver = webdriver.Chrome()
    #driver.set_window_size(920, 680)
    driver.get(url)

    driver.find_element_by_id("email").send_keys("xx")
    driver.find_element_by_id("pass").send_keys("yy")
    b = driver.find_element_by_id("loginbutton")

    print('wait for others')
    barrier.wait()

    print('click')
    b.click()

# ---

url = 'https://www.facebook.com/'

number_of_threads = 5

barrier = Barrier(number_of_threads)

threads = []

for _ in range(number_of_threads):
    t = Thread(target=func, args=(barrier,)) 
    t.start()
    threads.append(t)

for t in threads:
    t.join()
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much..I enhanced this same program if i load the dynamic url which is in excel,it is taking last url only.. My code : number_of_threads = sheet.nrows url=sheet.cell_value(i, 0)..
I don't know what you try to do but maybe you should send url as parameter to thread.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.