硒过程中的Tkinter冻结

时间:2018-10-24 16:04:39

标签: python selenium user-interface tkinter automation

第一次使用Tkinter。

我写了一个python脚本来从Facebook保存我的照片。我想制作一个GUI,并尝试了Tkinker。问题是当我按下开始按钮时,窗口冻结。程序继续进行,一切正常,但是我想在Tkinker窗口中显示输出,以显示程序在做什么。

这是我的代码:

import tkinter
from tkinter import *
import tkinter.messagebox as tkMessageBox
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
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.webdriver.firefox.options import Options as FirefoxOptions
import time
import sys
import urllib.request
from urllib.parse import quote_plus
from tqdm import tqdm
linksTaggedPic = []
linksPersonalPic = []

top = tkinter.Tk()
top.minsize(300,300)
top.geometry("500x500")
strOutput = ""

def loadPic():
    while True:
        numPic = len(driver.find_elements_by_class_name("uiMediaThumb"))
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(3)
        loadedPic = len(driver.find_elements_by_class_name("uiMediaThumb"))
        strOutput('Found ' + str(loadedPic) + ' pictures.')
        if numPic == loadedPic:
            break
        numPic = loadedPic

def downloadPic(arr,path):
    strOutput('Downloading pictures...')
    i = 1
    #for link in tqdm(arr):
    for link in arr:
        time.sleep(2)
        driver.get(link)
        wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'spotlight')))
        #time.sleep(5)
        strOutput('Get picture ' + str(i) + ' of ' + str(len(arr)) +'...')
        src = driver.find_element_by_class_name("spotlight").get_attribute("src")
        size = round((urllib.request.urlopen(src).length / 1024),2)
        strOutput("Size: " + str(size) + " Kb")
        while True:
            if size < 1:
                strOutput('Wrong pic, is too little, try again...')
                driver.get(link)
                wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'spotlight')))
                newSrc = driver.find_element_by_class_name("spotlight").get_attribute("src")
                newSize = round((urllib.request.urlopen(newSrc).length / 1024),2)
                size = newSize
                src = newSrc
            else:
                strOutput(str(size) + 'KB ok, downloading...')
                urllib.request.urlretrieve(src, path + 'pic_' + str(i) + '.jpg')
                break
        i = i+1

def saveLinks(arr):
    strOutput('Saving links...')
    links = driver.find_elements_by_class_name("uiMediaThumb")
    for x in tqdm(links):
        arr.append(x.get_attribute("href"))

def startJob():
    #start browser
    options = FirefoxOptions()
    options.add_argument("--headless")
    _browser_profile = webdriver.FirefoxProfile()
    _browser_profile.set_preference("dom.webnotifications.enabled", False)
    driver = webdriver.Firefox(firefox_profile=_browser_profile, executable_path=r'geckodriver.exe')
    wait = WebDriverWait(driver, 10)

    #login
    username = textBoxUsername.get('1.0','end-1c')
    password = textBoxPassword.get()
    showOutput("login...")
    driver.get("http://www.facebook.com")
    driver.find_element_by_id("email").send_keys(username)
    driver.find_element_by_id("pass").send_keys(password)
    driver.find_element_by_xpath("//input[@type='submit']").send_keys(Keys.RETURN)
    time.sleep(3)
    #open user photo page and load all pictures where the user is tagged
    showOutput("Login done.")
    driver.find_element_by_xpath("//*[@title='Profilo']").click()
    time.sleep(2)
    profileUrl = driver.current_url

    #get all download links of tagged pictures
    driver.find_element_by_xpath("//*[@data-tab-key='photos']").click()
    time.sleep(2)
    strOutput('Loading pictures where you are tagged...')
    loadPic()
    saveLinks(linksTaggedPic)

    #get all download links of personal pictures
    driver.get(profileUrl + '/photos_all')
    time.sleep(2)
    strOutput('Loading all your pictures...')
    loadPic()
    saveLinks(linksPersonalPic)

    downloadPic(linksTaggedPic,'C:\\Users\\spina\\Desktop\\fb\\taggedPhotos\\')
    downloadPic(linksPersonalPic,'C:\\Users\\spina\\Desktop\\fb\\personalPhotos\\')

    driver.quit()

def showOutput(str):
    strOutput = str
    outputLabel = Label(top, text = strOutput)
    outputLabel.grid(row=5,column=1)


usernameLabelText = StringVar()
usernameLabelText.set("Nome Utente")
usernameLabel = Label(top, textvariable=usernameLabelText, height=4)
usernameLabel.grid(row=1,column=1)

textBoxUsername = Text(top, height=1, width=50)
textBoxUsername.grid(row=1,column=2)

passwordLabelText = StringVar()
passwordLabelText.set("Password")
passwordLabel = Label(top, textvariable=passwordLabelText, height=4)
passwordLabel.grid(row=2,column=1)

textBoxPassword = Entry(top, show="*", width=50)
textBoxPassword.grid(row=2,column=2)

button = tkinter.Button(top, text ="Start", command = startJob)

button.grid(row=4,column=1)
top.mainloop()

有一种方法可以使其工作?还是应该寻找另一种构建GUI的方法?

1 个答案:

答案 0 :(得分:1)

在执行一些主要命令之前,或者在gui冻结的地方,放入以下行:

top.update()

问候, CCD的Chris van den Hoorn