简体   繁体   中英

Python beginner problems - Tkinter, Threading and bs4 module

Running Python 3.6.5 with Anaconda, I'm not used to PEP yet, so sorry for my shitty code :P

I'm looking for a program which will check HTML code, where online players are and check if there are any Game Masters online. This code should be for players that are watching films while playing and are 'afk' in the game and bcs its not allowed to be 'afk' - this window should warn them. So I made code like this.(Ignore comments - I was trying to make it look better with pandas but its way too much)

What am i looking for?

I used a keyword 'ADMINS' bcs their guild is called ADMINS. Whenever GM appears in the online list - pop a window with some warning (GM is online!) BUT when I used threading, the code is running over and over and more and more windows appears. Is there a possibility to make that window appear just once and refresh it in given interval? Or to have a one window open all the time which will show '-' if there are no GMs online and 'GM ONLINE' if there are?

I'm using tkinter for the first time and I'm not really sure how to make it now. If u give me an example, that would be awesome.

Thanks in advance!!

import sys
import urllib
import bs4 as bs

from tkinter import *
from tkinter import ttk
import threading

gm = 'ADMINS'

def repeat():
    threading.Timer(10, repeat).start()
    link = 'https://www.daemu.cz/zebricky/online/'
    request = urllib.request.Request(
        link, headers={'User-Agent': 'Mozilla/5.0'})
    source = urllib.request.urlopen(request).read()
    #pocet_na_webpage = re.search('je online (.+?) ', str(source)).group(1)
    #df_table = pd.read_html(source)[0]
    soup = bs.BeautifulSoup(source, "lxml")
    table = soup.table
    #filtering = df_table.filter(items=[0,1,3,6])
    table_rows = table.find_all('tr')
    for tr in table_rows:
        td = tr.find_all('td')
        row = [i.text for i in td]
        #print(row)
    if gm in row:
        root = Tk()
        label = ttk.Label(root, text="GM je ONLINE!")

        label.pack()

        root.mainloop()

    else:
        print('-')


repeat()

# prazdny_list = []
# for i in range(0,len(row)):
#     if row == gms:
#         prazdny_list.append(True)
#     else:
#         prazdny_list.append(False)
# row['sloupec'] = prazdny_list

# print(row)

My problem here is, that sometimes the code works but sometimes it doesn't and i don't really know why. :D It gives me '-' all the time even if an account appears in the list of online ppl. Just change the gm variable to something different from the page. (for example: 'Teriyaki' or something else) Thanks anyway Nummer_42O, u really helped me a lot. :P

EDIT: I think I know where the problem is. Pasted the part of code. When I was checking the process, I found out, that this is only checking the last row. Any ideas?

import sys
import urllib
import bs4 as bs
from tkinter import *
from tkinter import ttk
import threading
gm =('ADMINS')
root = Tk(className='Status')
v = StringVar()
v.set('-')
style = ttk.Style()
style.configure("red.TLabel", foreground = "red")
label = ttk.Label(root, textvariable=v, style = "red.TLabel")
label.pack()
#print(v.get())


def check():
    link = 'https://www.daemu.cz/zebricky/online/'
    request = urllib.request.Request(
        link, headers={'User-Agent': 'Mozilla/5.0'})
    source = urllib.request.urlopen(request).read()
    #pocet_na_webpage = re.search('je online (.+?) ', str(source)).group(1)
    #df_table = pd.read_html(source)[0]
    soup = bs.BeautifulSoup(source, "lxml")
    table = soup.table
    #filtering = df_table.filter(items=[0,1,3,6])
    table_rows = table.find_all('tr')
    for tr in table_rows:
        td = tr.find_all('td')
        row = [i.text for i in td]
        #print(row)
        if str(gm) in str(row) and v.get() == ('-'):
            v.set('GM je ONLINE!')
            break
        elif str(gm) not in str(row) and v.get() == ('GM je ONLINE!'):
            v.set('-')
        #print(v.get())


def repeat():
    thread = threading.Timer(10, repeat)
    try:
        check()
        thread.start()
        root.update()
    except KeyboardInterrupt:
        root.destroy()
        thread.cancel()
        pass
    pass

repeat()
root.call('wm', 'attributes', '.', '-topmost', '1')
root.mainloop()

If I understood your answer correctly you want that little Tkinter-window to either just show if something changed or to just change its text, right? So for me, the way with less code would be the second one. Therefor I would start up that window in first place and just configure it by label.config(text=<text>) .

So to make it more clear for you - this should work:

import sys
import urllib
import bs4 as bs

from tkinter import *
from tkinter import ttk
import threading

gm = 'ADMINS'

root=Tk(className='Status')
label=ttk.Label(root,text='-')
label.pack()

def repeat():
    threading.Timer(10, repeat).start()
    link = 'https://www.daemu.cz/zebricky/online/'
    request = urllib.request.Request(link, headers={'User-Agent': 'Mozilla/5.0'})
    source = urllib.request.urlopen(request).read()
    #pocet_na_webpage = re.search('je online (.+?) ', str(source)).group(1)
    #df_table = pd.read_html(source)[0]
    soup = bs.BeautifulSoup(source, "lxml")
    table = soup.table
    #filtering = df_table.filter(items=[0,1,3,6])
    table_rows = table.find_all('tr')
    for tr in table_rows:
        td = tr.find_all('td')
        row = [i.text for i in td]
        #print(row)
    if gm in row and label.cget('text')=='-':
        label.config(text='GM je ONLINE!')
    elif gm not in row and label.cget('text')=='GM je ONLINE!':
        label.config(text='-')


repeat()
root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM