You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python募捐爬取脚本转为带UI的Windows可执行程序?

问题描述

我是软件工程专业大二本科生,每周为本地小型慈善机构提供志愿工作。我编写了一款Python脚本,可读取包含募捐URL的CSV文件,爬取JustGiving/GoFundMe页面的募捐数据并生成Excel文件。下月我即将离开,希望将该脚本转换为无技术背景人员可直接操作的、带UI的Windows可执行程序。请问:

  • 实现这一需求的最简单方式是什么?
  • 适用的开发语言有哪些?
  • 推荐使用什么IDE?

我的技术经验涵盖Java、Javascript、HTML、CSS、Kotlin、Android Studio及Python。脚本代码如下:

import requests
import re
from bs4 import BeautifulSoup
import pandas as pd
import os

print("\n_____Start Program_____")

def getTotal(urls):

    totalData = []
    for url in urls:

        print("\nurl: ", url)
        totalRaised = None
        giftAid = None
        target = None

        if 'justgiving' in url:
            elements = getElementsjg(url)
            #print('getTotal:',elements)    
        elif 'gofundme' in url:
            elements = getElementsgfm(url)
            #print('getTotal:',elements)
        else:
            elements = [None, None, None]

        totalRaised = elements[0]
        giftAid = elements[1]
        target = elements[2]

        print("Total raised:", totalRaised)
        print("Gift Aid:", giftAid)
        print('Target:', target)
        totalData.append([url, totalRaised, giftAid, target])

    return totalData


def getUrls(file):

    fileRead = open(file, "r")
    Lines = fileRead.readlines()
    fileRead.close()

    urls = []
    for line in Lines:  
        urls.append(line.strip())
    return urls


def processStringjg(totalString):

    if isinstance(totalString, str):
        totalString = totalString.replace(',', '')
        pattern = re.compile(r'\-?\d+\.\d+')
        totalNum = list(map(float, re.findall(pattern, totalString)))
        #print('processStringjg:',totalNum)        
        if len(totalNum)==2:
            totalNum.insert(2, None)
            #print('processStringjg:',totalNum)
            return totalNum
        elif len(totalNum)==1:
            totalNum.insert(1, None)
            totalNum.insert(2, None)
            #print('processStringjg:',totalNum)      
            return totalNum      
    else:
        return [None, None, None]


def processStringgfm(totalString):
    
    if isinstance(totalString, str):
        totalString = totalString.replace(',', '')
        #totalString = totalString.replace('.', '')
        totalNum = list(map(float, re.findall(r'\d+', totalString)))
        totalNum.insert(1, None)
        #print('processStringgfm:',totalNum)
        return totalNum
    else:
        print('Not a String')
        return [None, None, None]


def getElementsjg(url):

    resp=requests.get(url)
    if resp.status_code==200:

        # we need a parser,Python built-in HTML parser is enough
        soup=BeautifulSoup(resp.text,'html.parser')

        # l is the list which contains all the text i.e news
        l=soup.find("dd",{"class":"jg-pages-donationsummary__total jg-space-mbsm jg-text-color-branded"})
        text= l.text
        #print('getElementsjgtext:',text)
    else:
        print("Unable to reach site!!")
        text = None
        target = None

    elements = processStringjg(text)
    #print('getElementsjg:',elements)
    return elements


def writeToFile(totalList, file):
    df = pd.DataFrame(totalList, columns =['URL','Total Raised','Gift Aid', 'Target'])
    
    with pd.ExcelWriter(file) as tf:
        df.to_excel(tf, sheet_name='Sheet1')
    print('\n_____Data successfully scraped_____')


def getElementsgfm(url):

    resp=requests.get(url)
    if resp.status_code==200:

        # we need a parser,Python built-in HTML parser is enough .
        soup=BeautifulSoup(resp.text,'html.parser')

        # l is the list which contains all the text i.e news
        l=soup.find('p',{'class':"m-progress-meter-heading"})
        text = l.text
        #print('getElementsgfm:',text)
    else:
        print("Unable to reach site!!")
        text = None

    elements = processStringgfm(text)
    #print('getElementsgfm:',elements)
    return elements


def getReadFile():
    userFile = input('Please enter filename:')
    return userFile


def getWriteFile():
    path = os.path.realpath(__file__)
    return path[:-21] + '\data\donations_total.xlsx'


def runProgram():
    userFile = getReadFile()
    urls = getUrls(userFile)
    totalList = getTotal(urls)
    writeToFile(totalList, getWriteFile())

#print(getWriteFile())

runProgram()

print('\n_____End program_____')
解决方案

一、最简单的实现方式

基于你已有的Python脚本,用Python自带的Tkinter做GUI封装,再用PyInstaller打包成exe是最省心的方案,完全复用现有代码,不用切换语言:

  1. 加GUI界面:把控制台输入文件名改成Tkinter的文件选择对话框,把打印输出转到GUI文本框,添加一个“开始爬取”按钮,用户只需点击选择CSV文件,再点执行就能完成操作,不用碰命令行。
  2. 打包成exe:用PyInstaller把带GUI的脚本打包成单文件,用户双击就能运行,无需安装Python或任何依赖。

具体步骤:

  • 安装PyInstaller:pip install pyinstaller
  • 修改脚本,用Tkinter替换getReadFile()的输入逻辑,比如:
    from tkinter import Tk, filedialog
    def getReadFile():
        root = Tk()
        root.withdraw()
        userFile = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
        return userFile
    
  • 打包命令:pyinstaller --onefile --windowed your_script_name.py(--windowed参数会去掉运行时的控制台黑框)

二、适用的开发语言

  1. Python:首选,零迁移成本,GUI库选择丰富(Tkinter、PyQt、wxPython),打包工具成熟,完全匹配你的现有技术栈。
  2. Java/Kotlin:如果想用熟悉的Android Studio技术栈,可通过JavaFX或Swing开发桌面程序,再用jpackage打包成exe,但需要把Python脚本逻辑重写成Java/Kotlin,工作量大,没必要。
  3. Electron(JS/HTML/CSS):用你熟悉的前端技术写界面,通过Node.js调用Python脚本或把Python逻辑转成JS,但需要处理前后端交互,比纯Python方案复杂。

三、推荐IDE

  1. PyCharm:专业Python IDE,对GUI开发、打包工具集成友好,调试功能完善,适合快速改造现有脚本。
  2. VS Code:轻量编辑器,安装Python、Tkinter相关插件后,也能高效完成开发,适合习惯轻量工具的用户。
  3. IntelliJ IDEA:如果选择Java/Kotlin方案,它是首选,但对Python打包的支持不如PyCharm。

内容的提问来源于stack exchange,提问作者GandarfTheWhite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:42:56