Home > Mobile >  How do I open one URL at a time from text file with Selenium?
How do I open one URL at a time from text file with Selenium?

Time:12-19

I'm trying to open one URL at a time (in order as it is in the text file) when I click on the Test button. What my code does is open all URLs weirdly one after another repeatedly.

Text file:

https://google.com
https://yahoo.com
https://facebook.com
https://youtube.com

Here's the code:

import tkinter as tk

from random import *

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

from time import *

root = tk.Tk()

app_width = 1000
app_height = 620

screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)

root.geometry(f'{app_width}x{app_height} {int(x)} {int(y)}')

PATH ="C:\Program Files (x86)\chromedriver.exe"

testbtn_txt = tk.StringVar()
testbtn = tk.Button(root, textvariable=testbtn_txt, command=lambda:testfunc(), font="Arial", bg="#808080", fg="white", height=1, width=10)
testbtn_txt.set("Test")
testbtn.grid(row=10, column=0, columnspan=2, pady=5, padx=5)

def testfunc():
    global driver
    driver = webdriver.Chrome(PATH)

    sleep(5)
    f = open("updatedlist.txt")
    urls = [url.strip() for url in f.readlines()]
    for url in urls:
        driver.get(url)

    return driver

root.mainloop()

What am I doing wrong?

CodePudding user response:

First you read the URLs into a list and convert that list to an iterator. That allows to simply use next to get the next URL. So pressing the button will simply open the next URL and if there are no more to open it will stop the function from further execution:

import tkinter as tk
from selenium import webdriver


PATH ="C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)

with open('myfile.txt') as file:
    urls = iter([line.strip() for line in file])


def open_next():
    try:
        driver.get(next(urls))
    except StopIteration:
        print('no more urls')
        return


root = tk.Tk()

btn = tk.Button(root, text='Open next url', command=open_next)
btn.pack(padx=10, pady=10)

root.mainloop()

A couple of other things:
You don't need to use .readlines and it is better to use with (context manager) to open files. There is no need to use lambda in command if the function takes no arguments. Also don't use time, it has no place in this architecture since it freezes the entire thread and process and you rarely if ever want that to happen to a GUI. Also Variables such as StringVars are not really needed for Buttons, just use their text argument and if you need that to change use config.

Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.

CodePudding user response:

Your problem is caused by the fact you are opening the urls directly and immediately in the for loop

f = open("updatedlist.txt")
urls = [url.strip() for url in f.readlines()]
for url in urls:
    driver.get(url)

I'm not familiar with tkinter so I can't say how exactly your code should be, but the logic should be as following:

f = open("updatedlist.txt")
urls = [url.strip() for url in f.readlines()]
for url in urls:
    #here create a button based on the current url and click it
  • Related