尝试循环运行我的脚本,以便使用 BeautifulSoup 从网页收集的信息每隔 X 秒刷新一次。这需要在 Tkinter 运行时发生并且需要显示信息。
我目前发现我根本无法循环脚本。这是我的脚本
import tkinter as tk
root = tk=Tk()
root.title('Title')
from bs4 import BeautifulSoup, Navigable String
import requests
import time
page = requests.get("http://yourpage.com")
#get info from page
canvas.create_text(100, 100 text="text")
#display info
root.after(100,update)
root.mainloop()
我尝试放入 while True:
但没有成功。我认为这可能是 root.mainloop()
但我不知道如何解决这个问题,因为如果没有这个,GUI 就不会打开。
编辑
This is my code and it works where it will refresh, however, I don't think this is the proper way of doing it:
import tkinter as tk
root = tk.Tk()
root.title('title')
screen = tk.Canvas(root, width=400, height=600, background='gray15')
screen.grid()
root.iconbitmap(r'C:\\path\to\file.ico')
while True:
from bs4 import BeautifulSoup, NavigableString
import requests
import time
#SWDL Current
page = requests.get("https://yourwebpage.com")
page = requests.get("https://yourwebpage.com/page", cookies=page.cookies)
soup = BeautifulSoup(page.content, 'html.parser')
soup.find_all('td')
yourdata = soup.find_all('td')[12].get_text()
vara = yourdata[0:1]
varb = yourdata[1:2]
varc = yourdata[2:3]
var1 = int(vara)
var2 = int(varb)
var3 = int(varc)
offsets = (
(0, 0, 1, 0), # top
(1, 0, 1, 1), # upper right
(1, 1, 1, 2), # lower right
(0, 2, 1, 2), # bottom
(0, 1, 0, 2), # lower left
(0, 0, 0, 1), # upper left
(0, 1, 1, 1), # middle
)
# Segments used for each digit; 0, 1 = off, on.
digits = (
(1, 1, 1, 1, 1, 1, 0), # 0
(0, 1, 1, 0, 0, 0, 0), # 1
(1, 1, 0, 1, 1, 0, 1), # 2
(1, 1, 1, 1, 0, 0, 1), # 3
(0, 1, 1, 0, 0, 1, 1), # 4
(1, 0, 1, 1, 0, 1, 1), # 5
(1, 0, 1, 1, 1, 1, 1), # 6
(1, 1, 1, 0, 0, 0, 0), # 7
(1, 1, 1, 1, 1, 1, 1), # 8
(1, 1, 1, 1, 0, 1, 1), # 9
)
if yourdata == 'x':
class Digit:
def __init__(self, canvas, x=10, y=10, length=20, width=4):
self.canvas = canvas
l = length
self.segs = []
canvas.create_line(250, 53, 270, 8, width=3, fill="snow")
canvas.create_oval(250, 10, 255, 15, outline="snow", fill="snow", width=0)
canvas.create_oval(265, 46, 270, 51, outline="snow", fill="snow", width=0)
canvas.create_text(70, 30, text='info', font=('OCR A Extended', '18'), fill='snow')
for x0, y0, x1, y1 in offsets:
self.segs.append(canvas.create_line(
x + x0*l, y + y0*l, x + x1*l, y + y1*l,
width=width, state = 'hidden', fill='snow'))
def show(self, num):
for iid, on in zip(self.segs, digits[num]):
self.canvas.itemconfigure(iid, state = 'normal' if on else 'hidden')
dig = Digit(screen, 160, 10) ##
dig1 = Digit(screen, 190, 10) ##
dig2 = Digit(screen, 220, 10) ##
n = 0
def update():
global n
dig.show(var1)
dig1.show(var2)
dig2.show(var3)
n = (n+1) % 10
root.after(1000, update)
else:
class Digit:
def __init__(self, canvas, x=10, y=10, length=20, width=4):
self.canvas = canvas
l = length
self.segs = []
canvas.create_line(220, 53, 240, 8, width=3, fill="snow")
canvas.create_oval(220, 15, 225, 10, outline="snow", fill="snow", width=0)
canvas.create_oval(235, 46, 240, 51, outline="snow", fill="snow", width=0)
canvas.create_text(70, 30, text='info', font=('OCR A Extended', '18'), fill='snow')
for x0, y0, x1, y1 in offsets:
self.segs.append(canvas.create_line(
x + x0*l, y + y0*l, x + x1*l, y + y1*l,
width=width, state = 'hidden', fill='ghost white'))
def show(self, num):
for iid, on in zip(self.segs, digits[num]):
self.canvas.itemconfigure(iid, state = 'normal' if on else 'hidden')
dig = Digit(screen, 160, 10) ##
dig1 = Digit(screen, 190, 10) ##
n = 0
def update():
global n
dig.show(var1)
dig1.show(var2) ## Control what you want to show here , eg (n+1)%10
n = (n+1) % 10
root.after(1000, update)
root.after(1000, update)
root.update_idletasks()
root.update()
或者如果有一种方法只更新 beautifulsoup 也可以。
感谢任何帮助
最佳答案
您的示例有点稀疏,我们无法测试。然而,一个简单的解决方案是创建一个可以在您需要的任何时间间隔调用的函数。
这是一个基本示例:
def update_canvas():
canvas.delete("all")
canvas.create_text(100, 100, text=data_gathered)
root.after(100, update_canvas)
update_canvas()
通过在函数中使用 after()
,您可以避免阻塞主循环并能够保持持续更新。
编辑:
由于这一行,您的完整代码有点难以测试:
yourdata = soup.find_all('td')[12].get_text()
如果不知 Prop 体的网址,我就无法产生结果。 也就是说,我已经对您的代码进行了一些修改,使其能够更好地与主循环配合使用。我认为应该在某个时候将其全部转换为 OOP,这样就可以避免全局。
import tkinter as tk
from bs4 import BeautifulSoup
import requests
root = tk.Tk()
root.title('title')
screen = tk.Canvas(root, width=400, height=600, background='gray15')
screen.grid()
url_to_request = "https://google.com"
page = requests.get(url_to_request)
soup = BeautifulSoup(page.content, 'html.parser')
soup.find_all('td')
yourdata = soup.find_all('td')[12].get_text()
var1 = int(yourdata[0:1])
var2 = int(yourdata[1:2])
var3 = int(yourdata[2:3])
offsets = (
(0, 0, 1, 0), # top
(1, 0, 1, 1), # upper right
(1, 1, 1, 2), # lower right
(0, 2, 1, 2), # bottom
(0, 1, 0, 2), # lower left
(0, 0, 0, 1), # upper left
(0, 1, 1, 1), # middle
)
digits = (
(1, 1, 1, 1, 1, 1, 0), # 0
(0, 1, 1, 0, 0, 0, 0), # 1
(1, 1, 0, 1, 1, 0, 1), # 2
(1, 1, 1, 1, 0, 0, 1), # 3
(0, 1, 1, 0, 0, 1, 1), # 4
(1, 0, 1, 1, 0, 1, 1), # 5
(1, 0, 1, 1, 1, 1, 1), # 6
(1, 1, 1, 0, 0, 0, 0), # 7
(1, 1, 1, 1, 1, 1, 1), # 8
(1, 1, 1, 1, 0, 1, 1), # 9
)
def update(if_else_var):
global dig, dig1, dig2, n
soup = BeautifulSoup(requests.get(url_to_request).content, 'html.parser')
yourdata = soup.find_all('td')[12].get_text()
var1 = int(yourdata[0:1])
var2 = int(yourdata[1:2])
var3 = int(yourdata[2:3])
dig.show(var1)
dig1.show(var2)
if if_else_var:
dig2.show(var3)
n = (n+1) % 10
root.after(1000, update, if_else_var)
if yourdata == 'x':
global dig, dig1, dig2, n
class Digit:
def __init__(self, canvas, x=10, y=10, length=20, width=4):
self.canvas = canvas
canvas.delete('all')
l = length
self.segs = []
canvas.create_line(250, 53, 270, 8, width=3, fill="snow")
canvas.create_oval(250, 10, 255, 15, outline="snow", fill="snow", width=0)
canvas.create_oval(265, 46, 270, 51, outline="snow", fill="snow", width=0)
canvas.create_text(70, 30, text='info', font=('OCR A Extended', '18'), fill='snow')
for x0, y0, x1, y1 in offsets:
self.segs.append(canvas.create_line(x + x0*l, y + y0*l, x + x1*l, y + y1*l,
width=width, state='hidden', fill='snow'))
def show(self, num):
for iid, on in zip(self.segs, digits[num]):
self.canvas.itemconfigure(iid, state='normal' if on else 'hidden')
dig = Digit(screen, 160, 10)
dig1 = Digit(screen, 190, 10)
dig2 = Digit(screen, 220, 10)
n = 0
update(True)
else:
class Digit:
def __init__(self, canvas, x=10, y=10, length=20, width=4):
self.canvas = canvas
canvas.delete('all')
l = length
self.segs = []
canvas.create_line(220, 53, 240, 8, width=3, fill="snow")
canvas.create_oval(220, 15, 225, 10, outline="snow", fill="snow", width=0)
canvas.create_oval(235, 46, 240, 51, outline="snow", fill="snow", width=0)
canvas.create_text(70, 30, text='info', font=('OCR A Extended', '18'), fill='snow')
for x0, y0, x1, y1 in offsets:
self.segs.append(canvas.create_line(
x + x0*l, y + y0*l, x + x1*l, y + y1*l,
width=width, state='hidden', fill='ghost white'))
def show(self, num):
for iid, on in zip(self.segs, digits[num]):
self.canvas.itemconfigure(iid, state='normal' if on else 'hidden')
dig = Digit(screen, 160, 10)
dig1 = Digit(screen, 190, 10)
n = 0
update(False)
root.mainloop()
关于python - Tkinter 中清爽的 BeautifulSoup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54011261/