【发布时间】:2021-01-11 08:33:31
【问题描述】:
我已经阅读了一些关于线程、tkinter 停止按钮等的其他文章和问答。大部分想法都是关于如何停止一些小循环。但我的问题是我试图用我的 Tkinter GUI 包装我一个月前创建的现有函数。而且现有的功能相当庞大,所以我不知道我应该如何停止循环。这是代码。 Reader 对象读取输入文本文件并从网络抓取结果中输出 csvfile。它从输入的购物中心 url 中提取所有评论。你可以忽略所有的韩国人,这并不重要。还有另一个名为“SmartStoreReviewScraper”的对象,但功能非常简单。它基本上请求 GET 一个 json 文件将其返回给 Reader,以便它可以转换为 csvfile。
class Reader:
def __init__(self, filename, limit=None, delay_time=0):
self.filename = filename
self.limit = limit
self.delay_time = delay_time
self.target_variable = ['평점', '아이디', '시간', '구매옵션', '리뷰내용']
self.read_input_file()
self.extract_file()
def read_input_file(self):
request_df = pd.read_csv(self.filename, names=['names', 'link'], sep='*')
request_df = request_df.set_index('names')
request_df.index = request_df.index + request_df.groupby(level=0).cumcount().astype(str).replace('0','')
request_df.to_csv('output/wd.csv', encoding='utf-8', header=False)
def extract_file(self):
df = pd.read_csv('output/wd.csv', encoding='utf-8', names=['names', 'link'])
for i in range(len(df.index)):
file_name = list(df['names'])[i]
store_link = list(df['link'])[i]
print(f"###################{file_name} 수집 시작###################")
app = SmartStoreReviewScraper()
REVIEWS = app.scraped_reviews
store_data = app.get_store_data(store_link) #스토어 정보
json_review = app.get_review_json(store_data['merchant_no'], store_data['product_no'], 1) #리뷰 정보 리퀘스트
review_data = app.get_review_data(json_review) #해당 아이템 리뷰 (총 아이템수 + 총 페이지수) 정보
total_element = review_data['totalElements'] #총 아이템수
total_pages = review_data['totalPages'] #총 페이지수
print(f'총 아이템 수: {total_element}\n총 페이지 수: {total_pages}')
review_content = app.get_review_content(json_review) #목표 데이터
app.scrape_review_contents(REVIEWS, review_content) #첫 페이지 크롤링
if self.limit >= total_element or self.limit == 0:
self.start_scraper(app, REVIEWS, total_element, total_pages, store_data, file_name)
else:
self.start_scraper(app, REVIEWS, self.limit, total_pages, store_data, file_name)
def start_scraper(self, app, REVIEWS, LIMIT, PAGES, store_data, file_name):
print('목표 데이터 양:'+str(LIMIT))
DF = pd.DataFrame([], columns=self.target_variable)
while len(REVIEWS) < LIMIT:
for page in trange(2, PAGES+1, desc="크롤링 진행도"):
#첫 페이지는 이미 크롤링 완료하였으니 두번째 페이지부터 시작
json = app.get_review_json(store_data['merchant_no'], store_data['product_no'], page)
content = app.get_review_content(json)
app.scrape_review_contents(REVIEWS, content)
time.sleep(self.delay_time)
if len(REVIEWS) >= LIMIT:
break
for i in trange(len(REVIEWS), desc='데이터 변환 중'):
row = pd.DataFrame([REVIEWS[i]], columns=self.target_variable)
DF = DF.append(row, ignore_index=True)
DF.insert(0, column='번호', value=DF.index+1)
print("<데이터 프레임 샘플>")
print(DF.head())
print('데이터 수집 완료! 크롤링된 아이템 수:'+str(len(DF))+'\n')
DF.to_csv(f'output/data/{file_name}.csv', encoding='utf-8-sig', index=False)
这是进入我的 tkinter 根按钮的代码。我必须停止 Reader 对象,但我不知道该怎么做。我是线程新手,所以我不了解背后的整个机制。我每次都在阅读文档。但是有人可以建议我快速解决这个问题吗?因为我有点没时间了。
class Controller(object):
def __init__(self):
self.thread = None
self.stop_thread = Event()
def scraping(self):
while not self.stop_thread.is_set():
Reader(FILENAME[-1], limit=limit.get(), delay_time=delay_time.get())
messagebox.showinfo('info', 'finished crawling')
break
if self.stop_thread.is_set():
break
def start(self):
self.stop_thread.clear()
self.thread = Thread(target = self.scraping)
self.thread.start()
def stop(self):
self.stop_thread.set()
self.thread.join()
self.thread = None
control = Controller()
search_btn.grid(row=0, column=2)
start_btn = tk.Button(root, text='시작', command=control.combine)
start_btn.grid(row=2, column=2)
stop_btn = tk.Button(root, text='중지', command=control.stop)
stop_btn.grid(row=3, column=2)
我知道我必须在阅读器中插入某种停止功能。但我不知道我应该怎么做。任何形式的帮助都会非常有帮助,谢谢。
【问题讨论】:
标签: python multithreading user-interface tkinter process