解析 wxPython 和 Pandas 实现的 XLSX 分析器和网页打开器

news2024/10/25 23:22:06

在本文中,我们将分析一个使用 wxPython 和 Pandas 库编写的 Python 应用程序,名为 “XLSX Analyzer and Web Opener”。该应用程序的核心功能是:从 Excel 文件中读取数据并显示在网格中,此外,还允许用户使用 Google Chrome 批量打开 Excel 文件中的 URL 列表。
C:\pythoncode\new\analysisxlsx.py

全部代码

import wx
import wx.grid
import pandas as pd
import subprocess
import os

CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe"

class XlsxAnalyzerFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='XLSX Analyzer and Web Opener', size=(1200, 800))
        panel = wx.Panel(self)

        main_sizer = wx.BoxSizer(wx.VERTICAL)

        self.file_picker = wx.FilePickerCtrl(panel, wildcard="Excel files (*.xlsx)|*.xlsx")
        self.file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_file_selected)
        main_sizer.Add(self.file_picker, 0, wx.ALL | wx.EXPAND, 10)

        self.grid = wx.grid.Grid(panel)
        main_sizer.Add(self.grid, 1, wx.ALL | wx.EXPAND, 10)

        open_button = wx.Button(panel, label='Open URLs in Chrome')
        open_button.Bind(wx.EVT_BUTTON, self.on_open_urls)
        main_sizer.Add(open_button, 0, wx.ALL | wx.CENTER, 10)

        panel.SetSizer(main_sizer)
        self.Layout()
        self.Show()

        self.grid_created = False

    def on_file_selected(self, event):
        file_path = self.file_picker.GetPath()
        if file_path:
            try:
                df = pd.read_excel(file_path, sheet_name='sheet1')
                expected_columns = [
                    "blog-list-box href", "course-img src", "blog-list-box-top", 
                    "blog-list-content", "article-type", "view-time-box", "view-num", 
                    "give-like-num", "comment-num", "comment-num 2", "btn-edit-article href"
                ]
                if not all(col in df.columns for col in expected_columns):
                    raise ValueError("Excel file does not contain all expected columns")
                self.update_grid(df)
            except Exception as e:
                wx.MessageBox(f'Error reading file: {str(e)}', 'Error', wx.OK | wx.ICON_ERROR)

    def update_grid(self, df):
        if not self.grid_created:
            self.grid.CreateGrid(df.shape[0], df.shape[1])
            self.grid_created = True
        else:
            current_rows = self.grid.GetNumberRows()
            current_cols = self.grid.GetNumberCols()
            
            if current_rows < df.shape[0]:
                self.grid.AppendRows(df.shape[0] - current_rows)
            elif current_rows > df.shape[0]:
                self.grid.DeleteRows(0, current_rows - df.shape[0])
            
            if current_cols < df.shape[1]:
                self.grid.AppendCols(df.shape[1] - current_cols)
            elif current_cols > df.shape[1]:
                self.grid.DeleteCols(0, current_cols - df.shape[1])

        for i, col in enumerate(df.columns):
            self.grid.SetColLabelValue(i, str(col))
            for j, val in enumerate(df[col]):
                self.grid.SetCellValue(j, i, str(val))

        self.grid.AutoSizeColumns()
        self.grid.ForceRefresh()
        self.Layout()

    def get_urls(self):
        if self.grid.GetNumberRows() == 0:
            wx.MessageBox('No data loaded', 'Error', wx.OK | wx.ICON_ERROR)
            return []

        try:
            url_col_index = next(i for i in range(self.grid.GetNumberCols()) if "blog-list-box href" in self.grid.GetColLabelValue(i))
            return [self.grid.GetCellValue(row, url_col_index) for row in range(self.grid.GetNumberRows()) if self.grid.GetCellValue(row, url_col_index).strip()]
        except StopIteration:
            wx.MessageBox('Could not find "blog-list-box href" column', 'Error', wx.OK | wx.ICON_ERROR)
            return []

    def on_open_urls(self, event):
        if not os.path.exists(CHROME_PATH):
            wx.MessageBox(f'Chrome executable not found at {CHROME_PATH}', 'Error', wx.OK | wx.ICON_ERROR)
            return

        urls = self.get_urls()
        if not urls:
            return

        for i in range(0, len(urls), 10):
            batch = urls[i:i+10]
            for url in batch:
                try:
                    subprocess.Popen([CHROME_PATH, url])
                except Exception as e:
                    wx.MessageBox(f'Error opening URL {url}: {str(e)}', 'Error', wx.OK | wx.ICON_ERROR)
            
            if i + 10 < len(urls):
                should_continue = wx.MessageBox('Open next 10 URLs?', 'Continue',
                                                wx.YES_NO | wx.ICON_QUESTION)
                if should_continue == wx.NO:
                    break

if __name__ == '__main__':
    app = wx.App()
    frame = XlsxAnalyzerFrame()
    app.MainLoop()

核心功能概述

  1. 选择并解析 XLSX 文件:用户通过文件选择器选择一个 Excel 文件,程序读取其中的数据,并在网格中显示。
  2. 批量打开 URL:如果 Excel 文件包含一个 URL 列,用户可以点击按钮,程序会批量使用 Chrome 打开这些 URL。
  3. 错误处理:当文件不符合预期格式,Chrome 浏览器不可用或打开 URL 失败时,程序会显示相应的错误消息。

导入的库

import wx
import wx.grid
import pandas as pd
import subprocess
import os
  • wxwx.grid:用于创建图形用户界面(GUI),包括窗口、文件选择器、按钮和数据网格。
  • pandas (pd):用于从 Excel 文件中读取数据,并处理这些数据以显示在 GUI 网格中。
  • subprocess:用于通过系统命令启动 Chrome 浏览器。
  • os:用于检查 Chrome 浏览器的路径是否存在。

Google Chrome 路径

CHROME_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe"

该常量存储了 Chrome 浏览器的路径,程序将使用这个路径来启动 Chrome。如果用户的系统上 Chrome 位于不同的路径,需要修改该值。

XlsxAnalyzerFrame

主框架类 XlsxAnalyzerFrame 继承自 wx.Frame,实现了应用的 GUI 和逻辑。下面是它的初始化部分:

class XlsxAnalyzerFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='XLSX Analyzer and Web Opener', size=(1200, 800))
        panel = wx.Panel(self)

        main_sizer = wx.BoxSizer(wx.VERTICAL)

        self.file_picker = wx.FilePickerCtrl(panel, wildcard="Excel files (*.xlsx)|*.xlsx")
        self.file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_file_selected)
        main_sizer.Add(self.file_picker, 0, wx.ALL | wx.EXPAND, 10)

        self.grid = wx.grid.Grid(panel)
        main_sizer.Add(self.grid, 1, wx.ALL | wx.EXPAND, 10)

        open_button = wx.Button(panel, label='Open URLs in Chrome')
        open_button.Bind(wx.EVT_BUTTON, self.on_open_urls)
        main_sizer.Add(open_button, 0, wx.ALL | wx.CENTER, 10)

        panel.SetSizer(main_sizer)
        self.Layout()
        self.Show()

        self.grid_created = False
界面元素:
  1. 文件选择器 (self.file_picker):允许用户选择 Excel 文件,并绑定 on_file_selected 事件处理函数。当用户选择文件时,该函数将解析并加载数据。

  2. 数据网格 (self.grid):这是用于显示 Excel 文件数据的表格。wx.grid.Grid 是 wxPython 提供的网格控件,允许显示类似 Excel 的数据表。

  3. 打开 URL 按钮 (open_button):该按钮用于批量打开 Excel 文件中的 URL。当用户点击按钮时,on_open_urls 事件处理函数会处理并打开这些 URL。

处理 Excel 文件

读取并加载 Excel 数据

当用户选择一个 Excel 文件时,触发 on_file_selected 事件:

def on_file_selected(self, event):
    file_path = self.file_picker.GetPath()
    if file_path:
        try:
            df = pd.read_excel(file_path, sheet_name='sheet1')
            expected_columns = [
                "blog-list-box href", "course-img src", "blog-list-box-top", 
                "blog-list-content", "article-type", "view-time-box", "view-num", 
                "give-like-num", "comment-num", "comment-num 2", "btn-edit-article href"
            ]
            if not all(col in df.columns for col in expected_columns):
                raise ValueError("Excel file does not contain all expected columns")
            self.update_grid(df)
        except Exception as e:
            wx.MessageBox(f'Error reading file: {str(e)}', 'Error', wx.OK | wx.ICON_ERROR)
  1. file_path = self.file_picker.GetPath():获取用户选择的文件路径。
  2. pd.read_excel():使用 Pandas 从 Excel 文件中读取数据。程序假定数据位于名为 'sheet1' 的工作表中。
  3. expected_columns:指定预期的列名。如果 Excel 文件不包含所有这些列,程序会抛出异常并显示错误消息。
更新数据网格

数据成功加载后,通过 update_grid 函数将数据更新到网格中:

def update_grid(self, df):
    if not self.grid_created:
        self.grid.CreateGrid(df.shape[0], df.shape[1])
        self.grid_created = True
    else:
        current_rows = self.grid.GetNumberRows()
        current_cols = self.grid.GetNumberCols()
        
        if current_rows < df.shape[0]:
            self.grid.AppendRows(df.shape[0] - current_rows)
        elif current_rows > df.shape[0]:
            self.grid.DeleteRows(0, current_rows - df.shape[0])
        
        if current_cols < df.shape[1]:
            self.grid.AppendCols(df.shape[1] - current_cols)
        elif current_cols > df.shape[1]:
            self.grid.DeleteCols(0, current_cols - df.shape[1])

    for i, col in enumerate(df.columns):
        self.grid.SetColLabelValue(i, str(col))
        for j, val in enumerate(df[col]):
            self.grid.SetCellValue(j, i, str(val))

    self.grid.AutoSizeColumns()
    self.grid.ForceRefresh()
    self.Layout()

该函数根据 Excel 文件的行数和列数动态调整网格大小,并逐行逐列填充数据。

批量打开 URL

程序从 Excel 文件中获取一个名为 "blog-list-box href" 的列,用户可以点击按钮,程序会逐批打开这些 URL。每次打开 10 个 URL,并询问用户是否继续:

def on_open_urls(self, event):
    if not os.path.exists(CHROME_PATH):
        wx.MessageBox(f'Chrome executable not found at {CHROME_PATH}', 'Error', wx.OK | wx.ICON_ERROR)
        return

    urls = self.get_urls()
    if not urls:
        return

    for i in range(0, len(urls), 10):
        batch = urls[i:i+10]
        for url in batch:
            try:
                subprocess.Popen([CHROME_PATH, url])
            except Exception as e:
                wx.MessageBox(f'Error opening URL {url}: {str(e)}', 'Error', wx.OK | wx.ICON_ERROR)
        
        if i + 10 < len(urls):
            should_continue = wx.MessageBox('Open next 10 URLs?', 'Continue',
                                            wx.YES_NO | wx.ICON_QUESTION)
            if should_continue == wx.NO:
                break
核心步骤:
  1. 检查 Chrome 路径:首先检查 Chrome 浏览器是否存在于指定路径中。
  2. 获取 URL 列表:调用 get_urls 函数,提取网格中的 URL 列表。
  3. 分批打开 URL:使用 subprocess.Popen 启动 Chrome 并打开这些 URL。每次打开 10 个 URL,并询问用户是否继续打开下一个 10 个 URL。

运行结果

在这里插入图片描述

总结

此程序实现了通过 Excel 文件进行数据分析,并能够批量打开其中的 URL。它结合了 wxPython 用于构建 GUI、Pandas 用于处理 Excel 数据,以及 subprocess 来控制系统程序。程序还包含基本的错误处理和用户交互提示,适合在需要从表格数据中提取和操作 URL 的场景下使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣面试150 汇总区间 双指针 StringBuilder

Problem: 228. 汇总区间 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.ArrayList; import java.util.List;class Solution {public List<String> summaryRanges(int[] nums) {List<String> ret new ArrayList<String>(); // 存储结果的列表in…

Faster R-CNN模型微调检测航拍图像中的小物体

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

【排序算法】选择排序的全面剖析(含详细图解)

在之前文章中我们了解到了插入排序&#x1f449;【插入排序】&#xff0c;现在我们来学习排序算法中的直接选择排序。 目录 &#x1f4af;引言 &#x1f4af;选择排序的原理 &#x1f4af;选择排序的实现步骤 ⭐简单选择排序&#xff08;以升序为例&#xff09; ⭐代码实…

Human-M3 多模态姿态估计数据集-初步解读

文章概述(个人总结):该论文重点提出一个用于人体姿态估计的RGB+点云数据集,针对该多模态数据集,作者阐述了数据集的收集、数据标注以及该数据集的特点。并提出了一个简单的多模态3D人体姿态估计算法,对比其他模型,该方法性能较好。最后总结了该数据集和该方法的限制。 …

沪尚茗居装修秘籍:嵌入式蒸烤箱,让厨房生活更精彩

在装修厨房时&#xff0c;选择一款合适的嵌入式蒸烤箱不仅能提升烹饪效率&#xff0c;还能为厨房增添一份现代感。沪尚茗居深知用户对厨房电器的需求&#xff0c;从实际出发&#xff0c;为用户推荐选购嵌入式蒸烤箱的实用技巧&#xff0c;让厨房生活更加美好。    首先&…

【千库网-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

leetcode二叉树(二)-二叉树的递归遍历

题目 . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出…

滑块验证码,给图就行

效果如上~ <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>滑块拼图验证码 - 拖动条 Loading 效…

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理

背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为&#xff0c;如连接&#xff0c;发送消息&#xff0c;认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能&#xff0c;但是目前emqx仅仅支持单个grpc服务端的设置&#xff0c;所以会有…

视频格式转换

格式转换 1️⃣Convertio &#x1f3c6;优点 速度快、格式多、免费免登录 缺点 超过100m的文件就要登录付费了 点击进入 2️⃣123APPs &#x1f3c6;优点 这个免费的文件上限是10G&#xff0c;完完全全够用功能多、除了转换器格式还有视频、音频、PDF处理工具 缺点 广…

无人机飞手执照培训,三类、四类傻傻分不清楚

无人机飞手执照培训中的三类和四类&#xff0c;主要依据无人机的空机重量进行区分&#xff0c;并对应不同的飞行权限和应用场景。以下是对这两类执照的详细解析&#xff1a; 一、无人机飞手执照的三类与四类定义 1. 三类执照&#xff1a; 定义&#xff1a;三类执照是指允许操…

架构设计笔记-9-软件可靠性

目录 知识要点 综合知识 案例分析 1.可靠性特性&#xff0c;软硬件可靠性对比 论文 1.论软件可靠性设计技术的应用 知识要点 软件架构需求过程主要是获取用户需求&#xff0c;标识系统中所要用到的构件&#xff0c;并进行架构需求评审。其中&#xff0c;标识构件又详细地…

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份&#xff1a;RDB触发机制rdb的触发时机&#xff1a;手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置&#xff0c;自动生成rdb快照RDB的优缺点 实时备份&#xff1a;AOFAOF是否会影响到red…

去耦电容的“滤波半径”

1、简介 去耦电容的滤波半径通常指的是在电路板上&#xff0c;去耦电容能够对其周围电源线路或信号线路产生有效去耦作用的范围。这个范围是以去耦电容为中心&#xff0c;向周围扩展的一个特定距离。 想象你有一个水桶&#xff0c;里面装满了混浊的水&#xff08;含有噪声的信…

基于ESP32的厨房计时器

基于ESP32的厨房计时器 一、项目说明二、项目材料三、OLED显示屏四、外壳设计五、外壳打印六、电路和外壳的集成七、编程八、成品展示 一、项目说明 厨房计时器很有用&#xff0c;但现在没有多少人使用实体厨房计时器了。我个人还是喜欢使用它们&#xff0c;因为拥有一个可以按…

CGAL 带约束的Delaunay三角剖分

CGAL 带约束的Delaunay三角剖分 本文使用CGAL进行简单的2D Delaunay 三角剖分,添加内外边界及点作为约束剖分。 Code #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Constrained_Delaunay_triangulation_2.h> #include <…

问题杂录-NVIDIA Bluefield DPU bfb-build编译报错记录与处理办法?(无数坑)

文章目录 背景bfb-build之后直接退出docker.io无法访问报错 ERROR: failed to solve: processkubernotes 下载失败报错mlnx-fw-updater-signed-24.07-0.6.1.1.aarch64: Cannot download报错 No match for argument: bf-release报错 放弃编译anolis&#xff0c;直接编译老版ubun…

RabbitMQ 入门(二)基本结构和消息模型

一、RabbitMQ的基本结构、角色和消息模型 MQ的基本结构&#xff1a; RabbitMQ中的一些角色&#xff1a; - publisher&#xff1a;生产者 - consumer&#xff1a;消费者 - exchange个&#xff1a;交换机&#xff0c;负责消息路由 - queue&#xff1a;队列&#xff0c;存储消息…

初步认识torch自定义算子

此篇为PyTorch 自定义算子&#xff1a;复现CPU和CUDA版的二维卷积的代码详解 这篇是为了展示setup在构建简单的cpp算子的使用 1.环境配置 整体结构如下图所示 pytorch_cpp_helper.hpp中准备了CPU版卷积需要的头文件 pytorch_cuda_helper.hpp和common_cuda_helper.hpp是cuda…

板级支持包构建1

开发板&#xff1a;STM32h743xi 编程软件&#xff1a;Keil 项目&#xff1a;GPIO外设操作&#xff08;彩色LED灯&#xff09; 学习打卡&#xff1a;Day2 学习地址&#xff1a;【野火】STM32 HAL库开发实战指南 教学视频 手把手教学STM32全系列 零基础入门CubeMXHAL库&#xff0…