当前位置: 首页 > news >正文

python3-python中的GUI,Tkinter的使用,抓取小米应用商店应用列表名称

一 Tkinter简介

本篇介绍python中的GUI,Tkinter的使用。代码例子,抓取小米应用商店应用列表名称并且显示在gui中。
Tkinter(即 tk interface,简称 “Tk”), 提供了GUI编程接口。Tkinter是Python 自带的标准库,因此无须另行安装,它支持跨平台运行,不仅可以在 Windows 平台上运行,还支持在 Linux 和 Mac 平台上运行。Tkinter编写的程序,也称为TK GUI程序。

GUI (Graphical User Interface)指的是“图形用户界面”。它是计算机图形学(CG)的一门分支,主要研究如何在计算机中表示图形,以及利用计算机进行图形的计算、处理和显示等相关工作。一个 GUI 程序一般由窗口、下拉菜单或者对话框等图形化组件构成,通过鼠标点击菜单栏、按钮或者弹出对话框的形式来实现人机互动,从而提升人机交互的体验。
GUI属于计算机科学技术领域中的一个概念,比如使用 C/C++ 语言开发的 Qt、GTK、Electron 等都属于 GUI 软件包。

二 Tkinter举例:

2.1 功能描述:

获取小米应用商店的应用列表名称,通过Tkinter GUI显示在屏幕上。
效果图:
在这里插入图片描述
代码实现思路:

1). gui的实现:使用Tkinter GUI相关控件;
2). 线程的实现和运用:网络请求需要在线程中完成;
3). 网络url的请求:使用requests和etree进行数据的获取和解析

2.2 代码:

2.2.1 gui代码:
# -*- coding: utf-8 -*-
# gui_main.py 文件
import os
import sys
import tkinter as tk
import threading
from gui_logic import logic  # 调用b文件中的logic类

from tkinter import messagebox

class GUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title('抓取数据')
        self.root.geometry("800x600+200+200")
        self.interface()
        self.status = -1

    def interface(self):
        """"界面编写位置"""
        #url
        self.LabelUrl = tk.Label(self.root,text="url")
        self.LabelUrl.grid(row=0, column=0, pady=10)

        self.EntryUrl = tk.Entry(self.root,width=62)
        self.EntryUrl.grid(row=0, column=1, pady=10)

        #page
        self.LabelPageId = tk.Label(self.root, text="page")
        self.LabelPageId.grid(row=1, column=0, pady=4)

        self.EntryPageId = tk.Entry(self.root,width=62)
        self.EntryPageId.grid(row=1, column=1, pady=4)

        self.Button0 = tk.Button(self.root, text="数据抓取", command=self.start_get_data, bg="#7bbfea")
        self.Button0.grid(row=3, column=1, pady=10)
        
        self.w1 = tk.Text(self.root, width=100, height=25)
        self.w1.grid(row=4, column=0, columnspan=3, padx=60)

    #参数check
    def check_param(self):
        # url: https://app.mi.com/catTopList/0
        # page_id:1
        url = self.EntryUrl.get()
        page_id = self.EntryPageId.get()

        
        print("url",url)
        if url == "":
            print("url param is space")
            return -1
        if page_id == "":
            print("page param is space")
            return -1;
        return 0;
        print("run logic")


    #真正的业务
    def getData(self):
        '''把b文件的类单独写一个方法'''
        url = self.EntryUrl.get()
        page_id = self.EntryPageId.get()

        w1 = self.w1
        logic().get_data(url,page_id, w1)

    #1. 获取数据,必须用线程
    def start_get_data(self):
        '''先进行参数check,再执行线程。子线程无法直接执行b的类,需要把b文件单独写一个方法,然后执行'''
        #先删除旧文件
        # pwd=os.path.dirname(os.path.abspath(sys.argv[0]))
        # delete_old_txt(pwd)
        res = self.check_param();
        if res<0:
            self.showMessage("参数不能为空");
        else:
            self.status = 0
            print("run logic")
            '''清空输入框'''
            self.w1.delete(1.0, "end")
            self.T = threading.Thread(target=self.getData)
            self.T.setDaemon(True)
            self.T.start()
    def showMessage(self,error_msg):
        messagebox.showinfo("参数错误",error_msg)

if __name__ == '__main__':
    a = GUI()
    a.root.mainloop()

代码说明:

1)GUI类用于界面的显示,包括两个Lable,两个Entry,和一个Button;
2)start_get_data:创建线程,该线程执行的方法是getData;
3)getData:调用logic().get_data方法,而logic是另外一个模块gui_logic中的类,在下面的gui_logic.py中会介绍。

2.2.2 logic类的定义:gui_logic.py文件
# -*- coding: utf-8 -*-
# gui_logic.py 文件
import time
from apps_get import run_main


class logic():
    def __init__(self):
        pass

    def main(self, url,page_id):
        print("[logic] url,page_id",url,page_id)
        res_list = run_main(url,page_id)
        print(res_list)
        if len(res_list)<=0:
            self.w1.insert(1.0,"error: 调用main时发生错误,可能原因是:已经存在目录")
        else:
            res_text = ','.join(res_list)
            self.w1.insert(1.0,res_text)

    def get_data(self, url,page_id,w1):
        '''调用main的方法'''
        self.w1 = w1
        self.main(url,page_id)

代码说明:

1)get_data方法被上面提到的线程调用;self.w1是ui控件,用于显示获取到的数据;
2)语句res_list = run_main(url,page_id):调用apps_get模块的对应的方法,去进行网络请求,将结果返回到res_list中;
3)self.w1.insert:将结果数据插入到gui控件,这样,在界面上就可以看到这个应用名称列表了。

2.2.3 通过网络请求获取应用列表:

代码:

# -*- coding: utf-8 -*-
import requests
from lxml import etree

# 获取应用列表
def get_app_list(url):
    headers = {
        #mac os
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
        #windows
        # 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
    }
    res = requests.get(url, headers=headers)
    content = res.content.decode()
    tree = etree.HTML(content)
    
    a_list = tree.xpath('//ul[@class="applist"]/li/h5/a')
    # print(a_list)
    app_list = []
    for a in a_list:
        app_name = a.xpath('./text()') # 应用名称
        print(app_name) 
        print(a.xpath('./@href'))  #超链接
        app_list.append(app_name[0])
    return app_list;

#####################gui(图形界面) 模式相关函数###########
#直接被gui调用
def run_main(url,page_id):
    url = url + "?page=" +  page_id
    return get_app_list(url)

####################main function###############      
if __name__ == '__main__':
    print("[main] start...");
    url = 'https://app.mi.com/catTopList/0?page=1'
    get_app_list(url)
#end main

说明:

1)run_main是gui调用接口,即logic中的res_list = run_main(url,page_id);
2)get_app_list是真正的网络请求入口:
(1)requests.get(url, headers=headers):获取网络数据;
(2)etree.HTML(content):将网络数据存放到为etree对象中;
(3)对etree对象进行tree.xpath解析,就能获取到想要的数据了。

再看一下运行结果:

% python3 gui_main.py

在这里插入图片描述

相关文章:

  • 公众号查题接口API
  • 提高「程序员」的思维方式
  • EasyExcel自定义Converter解决LocalDateTime系列时间日期转换的问题
  • Nginx限流优化
  • 洗地机暗战:蓝海到血海,内卷的尽头没有赢家
  • python神经网络编程 豆瓣,用python构建神经网络
  • 2-4.spring源码--BeanPostProcessor
  • Centos8/Rocky9/linuxmint-21/安装docker和docker安装python3.9【亲测有效】
  • 网课答案公众号接口API提供
  • 顺丰2022半年报:成绩单背后的业务韧性
  • 考研算法辅导课【合集】
  • LeetCode---SQL刷题5
  • xilinx ip xdc修改
  • 计算机组成原理_双口RAM和多模块存储器
  • 引用折叠 万能引用 模板参数推导
  • 0x05 Python数据分析,Anaconda八斩刀
  • MYSQL 的 IF 函数
  • MySQL-事务管理(基础)
  • nginx 配置多 域名 + 多 https
  • QQ浏览器x5内核的兼容性问题
  • quasar-framework cnodejs社区
  • Redis 懒删除(lazy free)简史
  • session共享问题解决方案
  • spring-boot List转Page
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • - 概述 - 《设计模式(极简c++版)》
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 技术发展面试
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 小程序开发中的那些坑
  • 优化 Vue 项目编译文件大小
  • ​比特币大跌的 2 个原因
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #1015 : KMP算法
  • #NOIP 2014# day.1 T2 联合权值
  • #QT(串口助手-界面)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (ZT)出版业改革:该死的死,该生的生
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (已解决)什么是vue导航守卫
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .Net中的设计模式——Factory Method模式
  • [20150707]外部表与rowid.txt
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [android] 手机卫士黑名单功能(ListView优化)
  • [Android]通过PhoneLookup读取所有电话号码
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [cogs2652]秘术「天文密葬法」
  • [Firefly-Linux] RK3568修改控制台DEBUG为普通串口UART