吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 647|回复: 7
收起左侧

[求助] python tk库打包后无效

[复制链接]
fff123123 发表于 2023-11-3 19:26
本帖最后由 fff123123 于 2023-11-3 22:07 编辑

使用tkiter和requests制作的ui小说爬取,在pycharm里面可以正常运行,点击按钮可以执行绑定事件,
但是打包后exe文件运行,点击搜索确认按钮无反应 即这个方法confirmation_search
文件结构
main.py
bin
    tk_ui.py
    requestsutils.py
    yuan.json
main.py为程序入口,然后启动tk_ui.py界面,在tk_ui里面按钮绑定了requestsutils中的一个网络请求方法,没有使用多线程
请问是为什么,是只有tkiter这样吗,我之前使用pyqt5打包的没有问题


main.py文件
from bin.tk_ui import MyApp


def main():
    app = MyApp()
    app.mainloop()


if __name__ == '__main__':
    main()

tk_ui.py文件
from tkinter import *
from tkinter import ttk, messagebox
import tkinter.font as tf
from . import requestutils


class MyApp(Tk):
    """继承Tk,创建自己的桌面应用程序类"""

    def __init__(self):
        """构造函数"""

        super().__init__()
        self.title('Frame')
        # self.iconbitmap('./bin/Tk.ico')
        self.geometry('800x500')
        # self.resizable(width=False, height=False)  # 阻止Python GUI的大小调整
        # 底界面
        self.frame = Frame(self, bg='#90c0c0')
        self.frame.pack(expand=True, fill=BOTH)
        self.frame2 = Frame(self.frame)  # 界面1
        self.frame3 = Frame(self.frame)  # 界面2
        self.frame4 = Frame(self.frame)  # 界面3

        self.current_page = self.frame2
        self.init_ui()

    def init_ui(self):
        """初始化界面"""
        # 书籍存储搜索结果的二维列表
        self.result = list()
        # 章节存储搜索结果的二维列表
        self.result2 = list()
        # 章节内容存储搜索结果的二维列表
        self.result3 = list()
        # 设置字体
        ft = tf.Font(family="微软雅黑", size=10)

        # frame1frame的第1个子控件,从左向右布局,按钮所在的控件
        frame1 = Frame(self.frame, bg='#f0f0f0')
        frame1.pack(side=LEFT)

        # 3Buttonframe2的子控件,自上而下布局
        Button(frame1, text='书架', width=10, command=self.first_page).pack(padx=5, pady=5)  # 切换为界面1
        Button(frame1, text='搜索', width=10, command=self.second_page).pack(padx=5, pady=5)  # 切换为界面2
        Button(frame1, text='阅读', width=10, command=self.third_page).pack(padx=5, pady=5)  # 切换为界面3

        # 第一个界面ui
        Label(self.frame2, text='界面1', bg='#90c0c0').grid(row=1, column=1, padx=10, pady=10)
        # 第二个界面ui
        # 顶部单独的一个frame
        frame2_1 = Frame(self.frame3, bg='#90c0c0')
        frame2_1.pack(side=TOP, fill="x")

        self.combo_source_book = ttk.Combobox(frame2_1, values=("全本免费小说", "某点中文网"), state='readonly')
        self.combo_source_book.current(1)  # 选择第一个
        self.combo_source_book.grid(row=0, column=1, padx=2, pady=2, sticky="nsew")

        self.entry_book_name = Entry(frame2_1, width=30)
        self.entry_book_name.grid(row=0, column=2, padx=2, pady=2, sticky="nsew")  # 书名获得
        Button(frame2_1, text='确认', width=12, command=self.confirmation_search). \
            grid(row=0, column=3, padx=2, pady=2, sticky="nsew")  # 搜索确认键

        # 设置行和列的权重
        frame2_1.grid_rowconfigure(0, weight=1)
        frame2_1.grid_columnconfigure(0, weight=1)
        frame2_1.grid_columnconfigure(1, weight=2)
        frame2_1.grid_columnconfigure(2, weight=1)

        # 搜索结果显示
        self.lb_books_name = Listbox(self.frame3)
        self.lb_books_name.pack(expand=True, side=TOP, fill=BOTH, padx=5, pady=5)
        # 绑定双点击函数 获取具体章节 内容
        self.lb_books_name.bind("<Double-Button-1>", lambda event: self.get_book(self.lb_books_name.curselection()))
        # 绑定单击函数 提示具体信息
        self.lb_books_name.bind("<<ListboxSelect>>",
                                lambda event: self.get_book_introduce(self.lb_books_name.curselection()))

        # 底部 书籍具体信息显示
        # 创建文本框
        self.book_introduce = Text(self.frame3, height=1)
        self.book_introduce.pack(expand=True, side=TOP, fill=BOTH, padx=5, pady=5)

        # 第三个界面ui
        frame3_1 = Frame(self.frame4, bg='#90c0c0')
        frame3_1.grid(row=0, column=0, padx=2, pady=2, sticky="nsew")

        frame3_2 = Frame(self.frame4, bg='#90c0c0')
        frame3_2.grid(row=1, column=0, padx=2, pady=2, sticky="nsew")

        self.frame4.grid_columnconfigure(0, weight=1)
        self.frame4.grid_rowconfigure(0, weight=1)
        self.frame4.grid_rowconfigure(1, weight=25)
        # 第一个frame
        self.frame3_1_name = StringVar()  # 获取书名
        Label(frame3_1, textvariable=self.frame3_1_name).grid(row=0, column=0, padx=2, pady=2, sticky="nsew")
        Button(frame3_1, text="上一章").grid(row=0, column=1, padx=2, pady=2, sticky="nsew")
        Button(frame3_1, text='下一章').grid(row=0, column=2, padx=2, pady=2, sticky="nsew")
        # 设置行和列的权重
        frame3_1.grid_rowconfigure(0, weight=1)
        frame3_1.grid_columnconfigure(0, weight=3)
        frame3_1.grid_columnconfigure(1, weight=1)
        frame3_1.grid_columnconfigure(2, weight=1)

        # 第二个frame
        self.lb_chapter_name = Listbox(frame3_2)
        # 绑定双点击函数 获取具体章节 内容
        self.lb_chapter_name.bind("<Double-Button-1>",
                                  lambda event: self.get_chapter_content(self.lb_chapter_name.curselection()))
        # 多行文本
        self.lb_chapter_info = Text(frame3_2, font=ft)

        self.lb_chapter_name.grid(row=0, column=0, padx=2, sticky="nsew")
        self.lb_chapter_info.grid(row=0, column=1, padx=2, sticky="nsew")
        # 设置行和列的权重
        frame3_2.grid_rowconfigure(0, weight=1)
        frame3_2.grid_columnconfigure(0, weight=1)
        frame3_2.grid_columnconfigure(1, weight=5)

        # 默认显示界面1,并记录当前界面
        self.current_page.pack(expand=True, side=LEFT, fill=BOTH, padx=5, pady=5)

    # 书籍搜索确认键
    def confirmation_search(self):
        s1 = self.combo_source_book.current()  # 书源
        print("" + str(s1) + "个书源")
        s2 = self.entry_book_name.get()  # 书名
        # 检查 清除listbox框内的内容
        numble = self.lb_books_name.size()
        if numble != 0:
            self.lb_books_name.delete(0, END)
        if s2 != "":
            # 根据书源搜索书
            self.result = requestutils.requests_util(s2, s1, 0)
            if self.result3 != '':
                self.lb_books_name.insert(END, "成功")
            else:
                self.lb_books_name.insert(END, "失败")
            print(self.result)
            # 把搜索结果显示在listbox
            for item in self.result:
                self.lb_books_name.insert(END, item[0] + "----" + item[1] + "\n\n")
        else:
            # 提示没有输入书名
            messagebox.showinfo('提示', '没有输入书名')

    # 具体书籍url 获取具体章节信息 章节内容
    def get_book(self, index):
        # 设置阅读界面的书名
        s = self.entry_book_name.get()  # 书名
        self.frame3_1_name.set(s)
        # 跳转到阅读界面
        self.third_page()
        for i in index:
            # 获取书的url
            # 获取书籍内容 /获取章节内容
            s = self.result[-1]
            # 网络请求获取章节信息
            s1 = self.combo_source_book.current()  # 书源
            # 检查 清除listbox框内的内容
            # 根据书源搜索具体书籍
            self.result2 = requestutils.requests_util(s, s1, 1)
            print(self.result2)
            # 清除阅读界面的章节数据
            self.lb_chapter_name.delete(0, END)
            # 设置阅读界面的章节数据
            for item in self.result2:
                # 添加章节名
                self.lb_chapter_name.insert(END, item[0])
            break

    # 获取章节内容
    def get_chapter_content(self, index):
        for i in index:
            # 获取书的url
            url = self.result2[-1]
            # 网络请求获取章节信息
            s1 = self.combo_source_book.current()  # 书源
            # 检查 清除listbox框内的内容
            # 根据书源搜索具体书籍
            self.result3 = requestutils.requests_util(url, -1, 2)
            print(type(self.result3))
            self.lb_chapter_info.delete(1.0, END)
            self.lb_chapter_info.insert(END, self.result3)

    # 获取书籍介绍
    def get_book_introduce(self, index):
        print(index)
        for i in index:
            # 显示书籍具体信息
            self.book_introduce.config(state=NORMAL)
            # 清除内容
            self.book_introduce.delete("1.0", END)
            self.book_introduce.insert("0.0",
                                       self.result[0] + "    " + self.result[1] + "\n\n" + self.result[2])
            self.book_introduce.config(state=DISABLED)
            break

    # 跳转到第一个ui
    def first_page(self):
        if self.current_page != self.frame2:
            self.current_page.pack_forget()  # 取消显示当前界面,并不是销毁
            self.current_page = self.frame2
            self.current_page.pack(expand=True, side=LEFT, fill=BOTH, padx=5, pady=5)  # 显示界面1

    # 跳转到第二个ui
    def second_page(self):
        if self.current_page != self.frame3:
            self.current_page.pack_forget()  # 取消显示当前界面,并不是销毁
            self.current_page = self.frame3
            self.current_page.pack(expand=True, side=LEFT, fill=BOTH, padx=5, pady=5)  # 显示界面2

    # 跳转到第三个ui
    def third_page(self):
        if self.current_page != self.frame4:
            self.current_page.pack_forget()  # 取消显示当前界面,并不是销毁
            self.current_page = self.frame4
            self.current_page.pack(expand=True, side=LEFT, fill=BOTH, padx=5, pady=5)  # 显示界面3




requestsutils.py文件
import json
import random
import time
import requests
from bs4 import BeautifulSoup
from lxml import etree


# 随机返回请求头user_agent
def getheader():
    user_agent_list = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 "
        "Safari/537.36 Edg/117.0.2045.47",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"
    ]

    return random.choice(user_agent_list)


# 读取json文件
def getMovieUrl():
    with open("./bin/yuan.json", "r", encoding='utf-8') as file:
        t = file.read()
        link = json.loads(t)
        return link


# 普通网络请求 书名/完整书url 书源选择(0/1) 搜索书(0)/搜索书的具体信息(1)
def requests_util(search, book_source_item, coeffcient):
    # ip代{过}{滤}理
    proxy = {
        "http": "117.186.232.73:8080"
    }
    book_source_item = book_source_item + 1
    # 读取json文件
    item = getMovieUrl()
    item = item[book_source_item]

    # 存储搜索结果的二维列表
    result = list()

    # 网络请求准备
    name = item["bookSourceName"]
    url = item["bookSourceUrl"]
    search_url = item["search_url"]
    chapter_search_url = item["chapter_search_url"]
    headers = item["headers"]
    rules = item["rules"]
    rules_chapter = item["rules_chapter"]
    headers['User-Agent'] = getheader()

    # 搜索书
    if coeffcient == 0:
        # 需要拼接
        search_url += search
        print("书源名" + name, "书源网站" + url, "搜索网址" + search_url)
        response = requests.get(url=search_url, headers=headers, proxies=proxy, timeout=20)
    # 搜索具体书籍 章节
    elif coeffcient == 1:
        print("书源名" + name, "书源网站" + url, "搜索网址" + search)
        response = requests.get(url=search, headers=headers, proxies=proxy, timeout=20)
    # 搜索具体内容
    elif coeffcient == 2:
        print(name, "搜索网址" + search)
        response = requests.get(url=search, headers=headers, proxies=proxy, timeout=20)
    time.sleep(1)
    # response.encoding = response.apparent_encoding  # 设置编码,防止由于编码问题导致文字错乱
    # print(response.text)  # 查看请求到的内容
    content = response.content.decode("utf-8")
    soup = BeautifulSoup(content, "html.parser")
    # print(soup.text)
    if coeffcient == 0:
        print("搜索书籍")
        # 打印筛选结果
        t1 = rules["basics"]
        t2 = rules["book_name"]
        t3 = rules["book_author"]
        t4 = rules["info"]
        t5 = rules["url_part"]
        elements = soup.select(t1)
        # print(elements)
        for element in elements:
            # 基本信息
            s = list()
            print("具体文本信息:书名 作者 介绍")
            book_name = element.select_one(t2).text
            book_author = element.select_one(t3).text
            info = element.select_one(t4).text
            s.append(book_name)
            s.append(book_author)
            s.append(info)
            # url信息
            url_part = element.select_one(t5).get("href")

            spilt_after_url = url_part.split("book")[-1]
            new_url = chapter_search_url + spilt_after_url
            print("分割后字符串" + spilt_after_url)

            s.append(new_url)
            result.append(s)
            # 设置只保持10个搜索的结果
            if len(result) > 10:
                break
        # print(result)
        return result
    elif coeffcient == 1:
        print("搜索章节")
        # 返回 章节名 章节url
        t1 = rules_chapter["basics"]
        t2 = rules_chapter["part1"]
        elements = soup.select(t1)
        # print(elements)
        for element in elements:
            chapters = element.find_all(t2)
            for chapter in chapters:
                s = list()
                name = chapter.text
                part_url = chapter.get("href")
                # 找有没有前缀 没有 有前缀 删掉com之前的内容
                if "com" in part_url:
                    chapter_url = url + part_url.split("com", 1)[-1]
                else:
                    chapter_url = url + part_url
                # print(name)
                # print(url)
                s.append(name)
                s.append(chapter_url)
                result.append(s)
        return result
    elif coeffcient == 2:
        print("搜索章节内容")
        # 创建一个XPath解析器
        parser = etree.HTMLParser()
        tree = etree.HTML(content, parser=parser)
        # searchurl
        # 某点的规则 find(www.qidian.com)
        if "www.qidian.com" in search:
            # 使用XPath选择器筛选页面数据
            # 创建一个XPath解析器
            parser = etree.HTMLParser()
            tree = etree.HTML(content, parser=parser)
            # 使用XPath选择器筛选页面数据
            script_element = tree.xpath('//script[@id="vite-plugin-ssr_pageContext"]/text()')
            json_data = script_element[0].strip()
            data = json.loads(json_data)
            value = data['pageContext']['pageProps']['pageData']['chapterInfo']['content'].replace("<p>", "\n")
            print(value)
            return value

        # 全本的规则
        elif "www.qbmfxs.com" in search:
            # 使用XPath选择器筛选页面数据 str
            value = tree.xpath("/html/body/div[4]/div/div[1]/div[3]//p/text()")
            print(value)
            return value






这是main.spec文件

# -*- mode: python ; coding: utf-8 -*-


a = Analysis(
    ['main.py'],
    pathex=['D:\\other_folders\\code_workplace\\read_book'],
    binaries=[],
    datas=[('D:\\other_folders\\code_workplace\\read_book\\bin\\requestutils.py','bin'),('D:\\other_folders\\code_workplace\\read_book\\bin\\tk_ui.py','bin'),('D:\\other_folders\\code_workplace\\read_book\\bin\\yuan.json','bin\\yuan.json')],
    hiddenimports=['tkinter','requests'],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
)
pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='main',
)






发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| fff123123 发表于 2023-11-3 19:27
打包后exe执行后tk界面正常显示,但是按钮绑定事件没有反应
hrh123 发表于 2023-11-3 20:59
发了一大堆,感觉没说到重点啊
具体绑定的代码咋实现的?有没有对模块或程序做些其他处理?(我个人感觉是有的,不然整个hiddenimport还把主程序单独拉出来抽象一层干嘛)
sai609 发表于 2023-11-3 21:40
头像被屏蔽
rogabet 发表于 2023-11-3 21:46
提示: 作者被禁止或删除 内容自动屏蔽
yang4384 发表于 2023-11-3 22:00
不发问题的代码 上帝来了也不能帮你解决问题
 楼主| fff123123 发表于 2023-11-3 22:08
我是在pycharm里面运行没有问题,只是打包后exe文件使用有问题
 楼主| fff123123 发表于 2023-11-3 22:13
hrh123 发表于 2023-11-3 20:59
发了一大堆,感觉没说到重点啊
具体绑定的代码咋实现的?有没有对模块或程序做些其他处理?(我个 ...

hiddenimport我是在百度后说是可能没有导入模块,需要再次声明一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表