Home > Software engineering >  Selenium Perform actions at once like asyncio?
Selenium Perform actions at once like asyncio?

Time:12-02

Well i am new here so please ignore some mistakes taken by me for the description .

ok, I am having a form with 10 textboxes and 5 dropdowns and 2 date and time . So i wanted to start filling all the fields(textboxes,dropdowns and dates ) at once and after completing all fills i have to click a submit button.

I want to do something like the asyncio works.

import asyncio
import time

async def say_after(delay, what):

    await asyncio.sleep(delay)
    print(what)

async def main():
    task1 = asyncio.create_task(
        say_after(5, 'hello'))

    task2 = asyncio.create_task(
        say_after(7, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await task1
    await task2

   print(f"finished at {time.strftime('%X')}")

asyncio.run(main())

I already tried the method of threading like :

th1 = threading.Thread(target=__func_of_fill_1st_textbox__)
th2 = threading.Thread(target=__func_of_fill_2nd_textbox__)
th3 = threading.Thread(target=__func_of_fill_3rd_textbox__)
th4 = threading.Thread(target=__func_of_fill_4th_textbox__)
th1.start()
th2.start()
th3.start()
th4.start()

But sadly all are not executing at same time like asyncio.

Please Ignore if some mistakes taken by me.

Understandable answers appriciated .

CodePudding user response:

You say you want to do something like that asyncio script works. Using threads same output.

import threading
import time

def say_after(delay,what):
    time.sleep(delay)
    print(what)

print(f"started at {time.strftime('%X')}")
t1 = threading.Thread(target=say_after,args=(5,"hello"))
t2 = threading.Thread(target=say_after,args=(7,"world"))
t1.start()
t2.start()

#join() is what causes the main thread to wait for your thread to finish
t2.join()
print(f"finished at {time.strftime('%X')}")

CodePudding user response:

The problem is that Selenium have to communicate to a web browser engine, which loads and interacts with a web page like if it was a user: it does things in sequence - parallelizing the calls to the Selenium driver won't make it work in parallel. It maybe there is a "delay" option between setting controls which can be given to the Selenium driver itself - but I don't think so.

Otherwise, check if you really need Selenium to this task (it is needed for interacting with the page HTML itself, and a must if page elements are dynamically load with javascript code) - if all you need is a post request to the server, containing the form data, you can do that with the requests library, which is easily parallelizable with threads (or you can use an asyncio equivalent of requests). This approach submits your data as a single structure in one go, no need to interact with anything for each data field. (I think even Selenium may have a "post" option which could send all data in one go, instead of having to fill in all inputs in the interactive page - check here: Is there any way to start with a POST request using Selenium?)

If Selenium is your option, and you have several requests to do, you have to parallelize Selenium itself: start a new Selenium driver per thread, and instead of calling tasks in different threads for each control you have to fill, call a task that does the form filling, submission, response parsing and result saving in one go - and them parallelize these tasks. The amount of parallel browsers you can open this way is limited to the hardware resources on the computer you are running your script. (i.e. you create the equivalent of one full web browser per active selenium driver)

  • Related