如何在python中停止request.get

时间:2016-04-05 02:56:06

标签: python tkinter

我已经制作了一个tkinter应用程序,我有一个提交按钮,当我按下此按钮时,爬行请求转到request.get(url)方法,它从爬行开始,tkinter变为非活动状态,直到它给了我响应。但我希望在tkinter应用程序中另一个按钮“停止”,当按下时停止进程在后台进行,下次我想要我可以按提交按钮再次启动过程。 我已经尝试了破解和退出tkinter中可用的方法,但它们关闭了tkinter小部件本身。 我的代码是: -

#!/usr/bin/python
# -*- coding: latin-1 -*-
from Tkinter import *  
import thread
from tool_crawler import *
import tkMessageBox
import ttk

# function which accepts url from GUI and pass it further for the 
def crawl(url):
    time_delay =  time_delay_box.get() 

    if url == "Please enter URL.......":
        tkMessageBox.showerror("Error(错误)", "Please enter a valid URL(请输入有效网址)")

    elif not url:
        tkMessageBox.showerror("Error(错误)", "Please enter a valid URL(请输入有效网址)")


    else:
        tree.heading("#0", text=url)
        links = find_links(url, time_delay)
        #print links
        for i, link in enumerate(links):
            tree.insert("", i, str(i), text=link)
            tree.bind("<Double-1>", OnDoubleClick)

# function will invoke when any node in tree is double clicked      
def OnDoubleClick(event):
        item = tree.identify('item',event.x,event.y)        
        url = tree.item(item,"text")
        index = tree.index(item)
        parent = tree.parent(item)
        crawl_child(url,index,parent)


def crawl_child(url,index,parent):
    links = find_links(url, time_delay)
    #print links
    for i, link in enumerate(links):
        if not parent:
            tree.insert(str(index), i, str(index)+"."+str(i), text=link)
        else:
            tree.insert(str(parent)+"."+str(index), i, str(parent)+"."+str(index)+"."+str(i), text=link)

# tkinter object   
top = Tk()
top.configure(background='Lavender')

# window title
top.title("Fan Wan Crawler  ")

# tkinter minimum and maximum size
top.minsize(width=1460, height=800)
top.maxsize(width=1460, height=800)

# url entry area i.e. text box to enter the URLS
url = Entry(top, bd =3, width = 180)
url.insert(0, "Please enter URL.......")
url.pack(side = TOP)

# function to show and hide the text on entry and exit
def default(event):
    current = url.get()
    if current == "Please enter URL.......":
        url.delete  ("0", END)
    elif not current:
        url.insert("0", "Please enter URL.......")

 # code to call function default on focusin and focusout
url.bind("<FocusIn>", default)
url.bind("<FocusOut>", default)

# submit button which is performing action on submit
submit = Button(top, text="Submit(提交)", width=15, bg='lightblue',    command=lambda: crawl(url.get()))
submit.pack(side = TOP) 

# time delay label
time_label = Label(top, text="Time Dealy (时间延迟):", font=  ("Helvetica", 12), bg="Lavender", fg = "green")
time_label.place(x=2, y=27)

# time delay Entry
time_delay_box = Spinbox(top, from_=0, to=100, width=3)
time_delay_box.place(x=175, y=27)

# time description
time_label = Label(top, text="(in sec.(以秒为单位))", font=("Helvetica", 12), bg="Lavender", fg = "green")
time_label.place(x=220, y=27)

# tree area
tree = ttk.Treeview(top, selectmode="browse", height= "36")
columns = tree.column("#0", minwidth=0, width=720, stretch=True)

tree.place(x=2,y=56)

top.mainloop()

基本上我调用的是find_links函数,它存在于sepearte文件中并且具有函数request.get来抓取链接,目前我没有使用threads.So,有没有办法在不使用线程的情况下停止这个过程。我不想暂停它,我只想杀死这个过程。

1 个答案:

答案 0 :(得分:1)

您可以使用thread在另一个线程中开始抓取/抓取,然后创建一个暂停/恢复按钮,以启用&#34;暂停&#34;并且&#34; unpausing&#34;通过线程方法threading.Conditionthreading.Lock()

生成的线程

设置线程的一种方法示例,没有创建gui或任何东西只是显示了如何使用可暂停的线程和GUI中的按钮单击的示例,因为您如何选择设置/合并线程会有所不同。这假设在线程处理完当前request.get调用完成后将发生暂停和恢复。试图阻止线程死在任务中间是一个完全不同的问题。

import threading, requests
import tkinter as tk

def switch_thread_states(widget):

    #or whatever pause / resume text you wish for the widget / button
    if widget['text'] == 'Pause'
        widget['text'] = 'Resume'
    else:
        widget['text'] = 'Pause'
    for thread in threading.enumerate():
        if not isinstance(thread, threading._MainThread):
            if thread.paused:
                thread.resume()
            else:
                thread.pause()

 class PauseableThread(threading.Thread):

    def __init__(self, urls):

        threading.Thread.__init__(self)
        self.urls = urls
        self.paused = False
        self.pause_cond = threading.Condition(threading.Lock())

    def run(self):

        for url in self.urls:

            with self.pause_cond:
                while self.paused:
                   self.pause_cond.wait()
            #make requests here or whatever you're doing
            requests.get(url, headers={'User-Agent':'Mozilla/5.0 .....'})

    def pause(self):

        self.paused = True
        self.pause_cond.acquire()

    def resume(self):

        self.paused = False
        self.pause_cond.notify()
        self.pause_cond.release()

  #make root
  #make a button that calls switch_thread_states on press
  #spawn threads with urls lists etc