终于解决未响应问题了,还额外增加了个数据下载显示
import aiohttp
import asyncio
import aiofiles
import requests
from urllib.parse import quote
from lxml import etree
import os
from re import sub
import tkinter as tk
import ttkbootstrap as ttk
from tkinter import scrolledtext
from threading import Thread
class MangaDownloaderGUI():
def __init__(self, master):
self.master = master
master.geometry('600x371+{}+{}'.format(int((master.winfo_screenwidth() - 600) / 2),
int((master.winfo_screenheight() - 371) / 2)))
self.base_url = 'https://9y03.xyz'
self.label1 = ttk.Label(master, text="请输入漫画名称:", bootstyle='SUCCESS', font=("Helvetica", 16))
self.label1.pack(pady=10)
self.entry1 = ttk.Entry(master)
self.entry1.pack(pady=10)
self.button1 = ttk.Button(master, text="开始下载", command=self.start_download_thread, style='SUCCESS.OUTLINE')
self.button1.pack(pady=10)
self.progress_var = tk.StringVar()
self.progressbar = ttk.Progressbar(master, orient="horizontal", length=400, mode="determinate",
variable=self.progress_var)
self.progressbar.pack(pady=10)
self.frame = ttk.Frame(master)
self.frame.pack(pady=20)
self.scrolled_text = scrolledtext.ScrolledText(self.frame)
self.scrolled_text.pack()
def get_page(self, url):
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54',
'cookie': 'SL_G_WPT_TO=zh; SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1',
'referer': 'https://9y03.xyz/',
}
try:
with requests.get(url, headers=headers, timeout=(20, 50)) as response:
if response.status_code == 200:
return response.text
else:
return 'code error!'
except ConnectionError as e:
return
def parse(self, html):
dom_tree = etree.HTML(html)
r_url = dom_tree.xpath('//p[@class="comic__title"]/a/@href')[0]
detail_url = self.base_url + r_url
detail_page = self.get_page(detail_url)
detail_page_tree = etree.HTML(detail_page)
lis = detail_page_tree.xpath('//div[@class="chapter__list clearfix"]/ul/li')
for li in lis:
chapter_link = li.xpath('./a/@href')[0]
chapter_name = li.xpath('./a/text()')[0].strip()
mango_url = self.base_url + chapter_link
yield chapter_name, mango_url
def get_chapter(self, title, pics_url):
pic_page_html = self.get_page(pics_url)
pic_page_tree = etree.HTML(pic_page_html)
divs = pic_page_tree.xpath('/html/body/div[2]/div[5]')
for div in divs:
img_url = div.xpath('./div/img/@data-original')
img_name = div.xpath('./div/img/@alt')
yield list(zip(img_url, img_name))
async def download(self, url, name, folder_path):
async with aiohttp.ClientSession() as session:
async with session.get(url)as response:
img_content = await response.content.read()
await asyncio.sleep(0)
file_path = os.path.join(folder_path, name)
async with aiofiles.open(file_path, mode='wb')as f:
await f.write(img_content)
await asyncio.sleep(0)
self.progressbar.step(1)
self.progress_var.set(f"下载进度:{self.progressbar['value']}%") # 更新进度条的文本显示
async def main(self):
kw = self.entry1.get()
url = f'https://9y03.xyz/index.php/search?key={quote(kw)}'
html = self.get_page(url)
chapter_data = self.parse(html)
for chapter_title, chapter_url in chapter_data:
folder_path = f'{kw}\\'
title = sub(r'[\\/:\*\?"<>\|]', '', chapter_title)
folder_path = os.path.join(folder_path, title)
os.path.exists(folder_path) or os.makedirs(folder_path)
img_data = self.get_chapter(chapter_title, chapter_url)
tasks = []
num_tasks = 0
self.scrolled_text.insert(tk.END, f'正在下载>>> {title}' + '\n')
for data in img_data:
for pic_url, pic_name in data:
tasks.append(asyncio.create_task(self.download(pic_url, pic_name, folder_path)))
num_tasks += 1
self.progressbar["maximum"] = num_tasks # 设置进度条的最大值
self.progress_var.set("下载进度:0%") # 更新进度条的文本显示
await asyncio.gather(*tasks)
def start_download(self):
# loop = asyncio.get_event_loop()
# loop.run_until_complete(self.main())
# 报错不在事件循环中, 解决是既然没有event loop,把程序最初的loop传递到thread中去:
# asyncio.set_event_loop(loop) ,这个loop在程序主函数中保留好,传递到thread中去使用。
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.main())
def start_download_thread(self, ):
# 根据坛友 admib木木 的解答留言思路创建一个线程函数
t = Thread(target=self.start_download)
t.setDaemon(True)
t.start()
root = ttk.Window("漫画下载程序 by redballoon GUI:Trojians", "superhero")
my_gui = MangaDownloaderGUI(root)
root.mainloop()