我创建了一个使用Selenium网络驱动程序和tkinter界面的Instagram机器人。但是,当浏览器运行时,应用程序不会响应,不允许中途关闭它或其他任何东西。tkinter 应用程序在与实际代码不同的类中运行
import tkinter as tk
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import threading
import random
import sys
import mysql.connector
from mysql.connector import errorcode
from datetime import datetime
from tkinter import *
from tkinter.ttk import *
from time import strftime
from tkinter import messagebox
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
# THIS VERSION IS V 1.1.0
# THIS UPDATE INCLUDES THE NEW LAYOUT FOR THE GUI USING TTKINTER
# NEW MENUS ARE INCLUDED IN THIS UPDATE
# ADDED NUMBER OF PICTURES TO LIKE OPTION
# NEW FORMAT
# FIXED BUGS EXCLUDING RANDOM REDIRECTION ISSUE
# Note: This works with Chromedriver V77 and Chrome V77
class StartPage(tk.Tk):
# Load application
def __init__(self, root):
root.title("Instagram Bot - Created By HudZah")
# Creating menubar
menubar = Menu(root)
print("Application loading, please wait")
print("When you install this application, you agree to the abide by the Terms And Conditions stated in the installtion folder. This software is not intended to be used for the exploitation of Instagram, rather as a means of promoting your product. Any detention or suspension that is resulted due to excessive use of this Bot is in no means the fault of the publisher, but the consequences faced by the user. It should be clear that this Bot should not be misused or overused, this might result in unknown penalties to be faced by the user." + "n Created by HudZah")
Border = 3
canvas = tk.Canvas(root, height=600, width=700)
canvas.pack()
MainFrame = tk.Frame(root, bg="white")
MainFrame.place(relwidth=1, relheight=1)
# Adding file menu and commands
file = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "File", menu = file)
file.add_command(label ='New File', command = None)
file.add_command(label ='Run', command = lambda:GetUserInfo(Username.get(), Password.get(), List.get()))
file.add_command(label ='Save', command = None)
file.add_separator()
file.add_command(label ='Exit', command = root.destroy)
# Adding Edit Menu and commands
edit = Menu(menubar, tearoff = 0)
menubar.add_cascade(label ='Edit', menu = edit)
edit.add_command(label ='Cut', command = None)
edit.add_command(label ='Copy', command = None)
edit.add_command(label ='Paste', command = None)
edit.add_command(label ='Select All', command = None)
edit.add_separator()
edit.add_command(label ='Find...', command = None)
edit.add_command(label ='Find again', command = None)
# Adding Help Menu
help_ = Menu(menubar, tearoff = 0)
menubar.add_cascade(label ='Help', menu = help_)
help_.add_command(label ='Help', command = None)
help_.add_command(label ='Tutorials', command = None)
help_.add_separator()
help_.add_command(label ='About BOTIG', command = None)
UsernameFrame = tk.Frame(root, bg="lightgrey", bd=Border)
help_.add_command(label ='Information', command = None)
# Relative width to the canvas
UsernameFrame.place(relx=0.5, rely=0.135, relwidth=0.60,
relheight=0.1, anchor="n")
Username = tk.Entry(UsernameFrame, font=40)
Username.insert(0, "Username")
Username.place(relwidth=1, relheight=1)
Username.focus()
PasswordFrame = tk.Frame(root, bg="lightgrey", bd=Border)
PasswordFrame.place(relx=0.5, rely=0.26, relwidth=0.60,
relheight=0.1, anchor="n")
Password = tk.Entry(PasswordFrame, show="*", font=40)
Password.insert(0, "Password")
Password.place(relwidth=1, relheight=1)
ListFrame = tk.Frame(root, bg="lightgrey", bd=Border)
ListFrame.place(relx=0.5, rely=0.385, relwidth=0.60,
relheight=0.1, anchor="n")
List = tk.Entry(ListFrame, font=40)
List.insert(0, "Explore Hashtags, eg: food, nyc")
List.place(relwidth=1, relheight=1)
# Minutes
PicsInput = Spinbox(root, from_= 1, to = 2000, font = 13)
PicsInput.place(relx=0.5, rely=0.61, relwidth=0.14,
relheight=0.055, anchor = "n")
button = tk.Button(MainFrame, text="Run",
command=lambda:GetUserInfo(Username.get(), Password.get(), List.get(), PicsInput.get()))
button.place(relx=0.5, rely=0.71, relwidth=0.25,
relheight=0.085, anchor="n")
button = tk.Button(MainFrame, text="Quit",
command= root.destroy)
button.place(relx=0.5, rely=0.81, relwidth=0.25,
relheight=0.085, anchor="n")
label = tk.Label(root, text = "Created by HudZah © 2019", font = 13, bg = "white", fg = "black")
label.place(relx = 0.5, rely = 0.93, anchor = "n")
PicsInputLabel = tk.Label(root, text = "Pictures Per Hashtag", font = 7, bg = "white", fg = "black")
PicsInputLabel.place(relx = 0.5, rely = 0.55, relwidth = 0.3, anchor = "n")
# Create label to show errors to users and Info of bot when closed
root.config(menu = menubar)
#pyinstaller --add-binary="Documents/chromedriver.exe;." InstagramBotV1.1.0.py
class InstagramBot(tk.Tk):
# Run page
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = webdriver.Chrome()
def login(self):
driver = self.driver
driver.get("https://www.instagram.com/")
time.sleep(2)
LoginButton = driver.find_element_by_xpath(
"//a[@href='/accounts/login/?source=auth_switcher']")
LoginButton.click()
time.sleep(5)
UsernameElem = driver.find_element_by_xpath(
"//input[@name='username']")
UsernameElem.clear()
UsernameElem.send_keys(self.username)
PasswordElem = driver.find_element_by_xpath(
"//input[@name='password']")
PasswordElem.clear()
PasswordElem.send_keys(self.password)
PasswordElem.send_keys(Keys.RETURN)
time.sleep(6)
def LikePhoto(self, hashtag, NumOfPics, pages):
driver = self.driver
driver.get("https://www.instagram.com/explore/tags/" + hashtag + "/")
time.sleep(3)
# gathering photos
PicLinks = []
print("Check : Number of pages are", pages)
for i in range(0,pages):
try:
driver.execute_script(
"window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
# get tags
Links = driver.find_elements_by_tag_name('a')
# finding relevant hrefs
Links = [elem.get_attribute('href') for elem in Links
if ".com/p/" in elem.get_attribute("href")]
for i in range (0,len(Links)):
if Links[i] not in PicLinks:
PicLinks.append(Links[i])
print(
"Check: Total N.of pic hrefs stored after array : " + str(len(PicLinks)) + " , in " + hashtag)
# print(Links)
except Exception:
continue
LikedPhotos = 0
for i in range(0, len(PicLinks)):
print("Num" , i , " : " , PicLinks[i])
# Liking photos
UniquePhotos = int(NumOfPics)
#for PicLinks in Links:
for i in range(0,int(NumOfPics)):
driver.get(PicLinks[i])
time.sleep(4)
driver.execute_script(
"window.scrollTo(0, document.body.scrollHeight);")
try:
time.sleep(random.randint(5, 9))
#driver.find_element_by_xpath("//class[@glyphsSpriteHeart__outline__24__grey_9 u-__7]").click()
driver.find_element_by_xpath('//span[@aria-label="Like"]').click() # Anonymous function
time.sleep(1)
UniquePhotos = UniquePhotos - 1
LikedPhotos = LikedPhotos + 1
print("Picture liked : ",LikedPhotos , " Pictures left : ", UniquePhotos)
except Exception:
time.sleep(2)
def closeBrowser(self):
self.driver.close()
print("Browser quit")
# Pass info to main class
def GetUserInfo(username, password, hashtagReceived, nOfPics):
if password and username and hashtagReceived:
if username != "Username" and password != "Password" and hashtagReceived != "Explore Hashtags, eg: food, nyc":
try:
if int(nOfPics) != 0:
if messagebox.askokcancel('Application','Application is running, press OK to continue') == True:
hashtags = []
username = username
password = password
pages = int(nOfPics)/10
pages = int(pages)
if pages < 1:
pages = 1
else:
pages = pages
#print("username is ", username, "ands password is", password)
# Split hashtags into an array
hashtags = hashtagReceived.split(",")
try:
print(hashtags)
IG = InstagramBot(username, password)
IG.login()
i = 0
except:
messagebox.showerror("Could not execute task. Please try again.")
try:
while i <= len(hashtags):
# Choose a random tag from the list of tags
tag = hashtags[i]
tag = tag.replace(" ", "")
IG.LikePhoto(tag, nOfPics, pages)
i = i + 1
except ValueError:
print("Value could not be converted to an integer.")
except Exception:
if i != len(hashtags):
IG.closeBrowser()
print("Browser crashed")
time.sleep(3)
IG = InstagramBot(username, password)
IG.login()
i = 0
elif i == len(hashtags):
print("Hashtags are out")
finally:
print("Program finished")
IG.closeBrowser()
else:
SystemExit()
else:
messagebox.showwarning("Error", "Please enter a valid number of posts to like")
print("Please enter a valid number of posts to like")
except Exception:
messagebox.showwarning("Error", "Please enter a valid number of posts to like")
print("Please enter a valid number of posts to like")
else:
messagebox.showwarning("Error", "Please enter suitable data")
print("Please enter suitable data")
else:
messagebox.showwarning('Error', 'Please enter a username or password') #shows warning message
print("Please enter a username and password")
if __name__ == "__main__":
print("Run from main")
root = tk.Tk()
Start = StartPage(root)
root.mainloop()
else:
print("Run from import")
浏览器运行良好,代码有效。但是,如果您尝试单击应用程序上的任何按钮,它不会响应。它应该同时运行浏览器和运行应用程序
您面临的问题是因为硒和tkinter在同一线程/进程上运行,您需要使用线程模块或子进程模块来运行它,这样做您的tkinter应用程序将不再冻结。
线程文档可以在这里找到
子流程文档在这里
您可以在此链接上找到线程的一些实现