I have a bot, which should scrape website. We have one fixed given URL link placeholder (as an Entry in tkinter) it works well.
Also, I have add button with help of it, user adds as many as button-clicked entry boxes.
When I click scrape, I cannot take the text values from that newly added entry boxes.
here is code;
ListOfEntries=[]
fixed_entry = ttk.Entry(canvas1, width=79)
fixed_entry.place(relx=0.01, rely=0.0125)
fixed_entry.focus()
text_entryNumbers=[]
def addurlbox():
global extraentryBoxValue
extraentryBox = tk.Entry(canvas1,width=63)
extraentryBox.place(relx=0.01, rely=0.125 * (len(text_entryNumbers) 1))
text_entryNumbers.append(extraentryBox)
extraentryBoxValue=extraentryBox
def crawler():
entreeURL = fixed_entry.get()
ListOfEntries.append(entreeURL)
ListOfEntries.append(extraentryBoxValue.get())
for i in range(len(ListOfEntries)):
varUrl_SC = ListOfEntries[i]
I am able only to take fixed url entry value, and first added entry box value, I want to take values inside as many entry boxes added and use them inside loop in another function
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
canvas1 = tk.Canvas(root, width=420, height=330)
canvas1.pack()
lbllst=[]
fixed_entry = ttk.Entry(canvas1, width=63)
fixed_entry.place(relx=0.01, rely=0.125)
#canvas1.create_window(100, 20, width=300,window=fixed_entry)
fixed_entry.focus()
lbllst.append(fixed_entry)
def crawler():
xUrl='https://www.amazon.com/s?bbn=1&rh=n:1,p_n_feature_eighteen_browse-bin:8622846011&dc&qid=1666333032&rnid=8622845011&ref=lp_1_nr_p_n_feature_eighteen_browse-bin_4'
chrome_options=Options()
chrome_options.headless=False
chrome_options.add_argument('--window-size=1920,1200')
webdriver_service = Service(r'C:\pythonPro\w_crawl\AmznScrpBot\chromedriver.exe')
driver=webdriver.Chrome(
options=chrome_options,
service=webdriver_service)
driver.get(xUrl)
javaScript = "window.scrollBy(0, 1000);"
driver.execute_script(javaScript)
driver.save_screenshot(r'C:\pythonPro\w_crawl\AmznScrpBot\hn_homepage.png')
driver.quit()
def addurlbox():
textentry = tk.Entry(canvas1,width=63)
textentry.place(relx=0.01, rely=0.125 * (len(lbllst) 1))
lbllst.append(textentry)
def print_entry():
if lbllst!='':
for i in range(len(lbllst)):
print(lbllst[i].get())
add_account_button = tk.Button(canvas1, text="print", font='Segoe 9', command=print_entry)
add_account_button.place(relx=0.9, rely=0.713)
add_urlbox_button = tk.Button(canvas1, text="Add another URL", font='Segoe 9', command=addurlbox)
add_urlbox_button.place(relx=0.65, rely=0.033)
button1 = tk.Button(text='scrape', command=crawler, bg='darkblue', fg='white')
canvas1.create_window(300, 250, window=button1)
root.mainloop()
CodePudding user response:
There are different solutions to your problem and it is not clear what you really try to achieve. To give some examples:
Get widget that has currently the focus:
import tkinter as tk
def example():
print(root.focus_get())
root = tk.Tk()
canvas = tk.Canvas(root)
canvasframe = tk.Frame(canvas)
canvas.create_window(2,2, anchor=tk.NW, window=canvasframe)
for i in range(10):
entry = tk.Entry(canvasframe)
entry.pack()
tk.Button(root, command=example, text='example').pack()
canvas.pack()
root.mainloop()
But this might end up in a entirely different widgets, maybe one that neither has a get
method. You could check if it is an instance of tk.Entry
but you still could have clicked another tk.Entry
before clicking your button.
You could forget about the tk.Button
and bind a event to your return-key and get the widget by the event parameter:
import tkinter as tk
def example(event):
print(event.widget.get())
root = tk.Tk()
canvas = tk.Canvas(root)
canvasframe = tk.Frame(canvas)
canvas.create_window(2,2, anchor=tk.NW, window=canvasframe)
for i in range(10):
entry = tk.Entry(canvasframe)
entry.pack()
entry.bind('<Return>', example)
canvas.pack()
root.mainloop()
But if you insist to use a tk.Button
you also could bind the event sequence '<FocusIn>'
and have globally available path to that widget which you can use to find the widget.
import tkinter as tk
def example():
widget = root.nametowidget(last_entry.get())
print(widget.get())
root = tk.Tk()
canvas = tk.Canvas(root)
canvasframe = tk.Frame(canvas)
canvas.create_window(2,2, anchor=tk.NW, window=canvasframe)
last_entry = tk.StringVar()
for i in range(10):
entry = tk.Entry(canvasframe)
entry.pack()
entry.bind('<FocusIn>', lambda e:last_entry.set(e.widget))
tk.Button(root, command=example, text='example').pack()
canvas.pack()
root.mainloop()
But still, you could have missclicked to a different tk.Entry
but at least it will be one you have intended to use.
Be aware there for sure more ways to achieve what you want, but it seems your own intention about what your code should do is not clear yet. Work your idea out first and then start coding, otherwise you end up writing code over and over again.
I need to take all the values from all values of entry box, not depending how many of them are there. nd to use that values(url) inside crawler function
for ALL entries, you can use winfo_children
and check if it is an instance of tk.Entry
def example():
inputs = []
for widget in canvasframe.winfo_children():
if isinstance(widget, tk.Entry):
inputs.append(widget.get())
print(inputs)