欢迎光临UUpython
最大、最新、最全的Python代码收集站

信息管理系统

uupython阅读(428)

这段代码实现了一个简单的学生信息管理系统。用户可以通过命令行菜单选择不同的功能,包括录入学生信息、查找学生信息、删除学生信息、修改学生信息、排序学生信息、统计学生总人数以及显示所有学生信息。

主要功能和流程如下:

  1. 定义了一个menu()函数,显示系统菜单。
  2. 主程序main()中使用while循环来保持系统运行。用户根据菜单选项进行操作。
  3. 录入学生信息功能(insert()):用户可以逐个输入学生信息,信息包括ID、姓名、英语成绩、Python成绩和C语言成绩。学生信息被保存在一个字典中,并添加到学生列表。用户可以选择继续录入或退出。
  4. 保存学生信息(save(student)):将学生信息保存到文件,每个学生的信息以一行记录的形式保存。
  5. 查找学生信息功能(search()):用户可以选择按照ID或姓名查找学生信息,找到的学生信息被保存在一个查询结果列表中,并显示在屏幕上。
  6. 删除学生信息功能(delete()):用户输入要删除的学生ID,程序在文件中查找并删除对应的学生信息。
  7. 修改学生信息功能(modify()):用户可以根据ID找到要修改的学生信息,并更新信息。
  8. 排序学生信息功能(sort()):用户可以选择按照英语、Python、C语言成绩或总成绩进行排序,并指定升序或降序。
  9. 统计学生总人数功能(total()):统计已录入的学生总人数。
  10. 显示所有学生信息功能(show()):显示文件中的所有学生信息。
  11. show_student(studentList)函数:将学生信息格式化并显示在屏幕上。

请注意,这段代码是一个基于命令行界面的简单学生信息管理系统示例,没有使用数据库存储数据。在实际应用中,可能需要进一步完善和加强数据存储、输入验证、异常处理等方面的功能。

# _*_ coding:utf-8   _*_
import re  # 导入正则表达式模块
import os  # 导入操作系统模块
 
filename = "students.txt"  # 定义保存学生信息的文件名
 
 
def menu():
    # 输出菜单
    print('''
    ╔———————学生信息管理系统————————╗
    │                                              │
    │   =============== 功能菜单 ===============   │
    │                                              │
    │   1 录入学生信息                             │
    │   2 查找学生信息                             │
    │   3 删除学生信息                             │
    │   4 修改学生信息                             │
    │   5 排序                                     │
    │   6 统计学生总人数                           │
    │   7 显示所有学生信息                         │
    │   0 退出系统                                 │
    │  ==========================================  │
    │  说明:通过数字或↑↓方向键选择菜单          │
    ╚———————————————————————╝
    ''')
 
 
def main():
    ctrl = True  # 标记是否退出系统
    while (ctrl):
        menu()  # 显示菜单
        option = input("请选择:")  # 选择菜单项
        option_str = re.sub("\D", "", option)  # 提取数字
        if option_str in ['0', '1', '2', '3', '4', '5', '6', '7']:
            option_int = int(option_str)
            if option_int == 0:  # 退出系统
                print('您已退出学生成绩管理系统!')
                ctrl = False
            elif option_int == 1:  # 录入学生成绩信息
                insert()
            elif option_int == 2:  # 查找学生成绩信息
                search()
            elif option_int == 3:  # 删除学生成绩信息
                delete()
            elif option_int == 4:  # 修改学生成绩信息
                modify()
            elif option_int == 5:  # 排序
                sort()
            elif option_int == 6:  # 统计学生总数
                total()
            elif option_int == 7:  # 显示所有学生信息
                show()
 
 
'''1 录入学生信息'''
 
 
def insert():
    stdentList = []        # 保存学生信息的列表
    mark = True  # 是否继续添加
    while mark:
        id = input("请输入ID(如 1001):")
        if not id:  # ID为空,跳出循环
            break
        name = input("请输入名字:")
        if not name:  # 名字为空,跳出循环
            break
        try:
            english = int(input("请输入英语成绩:"))
            python = int(input("请输入Python成绩:"))
            c = int(input("请输入C语言成绩:"))
        except:
            print("输入无效,不是整型数值....重新录入信息")
            continue
        stdent = {"id": id, "name": name, "english": english, "python": python, "c": c}  # 将输入的学生信息保存到字典
        stdentList.append(stdent)  # 将学生字典添加到列表中
        inputMark = input("是否继续添加?(y/n):")
        if inputMark == "y":  # 继续添加
            mark = True
        else:  # 不继续添加
            mark = False
    save(stdentList)  # 将学生信息保存到文件
    print("学生信息录入完毕!!!")
 
 
# 将学生信息保存到文件
def save(student):
    try:
        students_txt = open(filename, "a")  # 以追加模式打开
    except Exception as e:
        students_txt = open(filename, "w")  # 文件不存在,创建文件并打开
    for info in student:
        students_txt.write(str(info) + "\n")  # 按行存储,添加换行符
    students_txt.close()  # 关闭文件
 
 
'''2 查找学生成绩信息'''
 
 
def search():
    mark = True
    student_query = []  # 保存查询结果的学生列表
    while mark:
        id = ""
        name = ""
        if os.path.exists(filename):  # 判断文件是否存在
            mode = input("按ID查输入1;按姓名查输入2:")
            if mode == "1":
                id = input("请输入学生ID:")
            elif mode == "2":
                name = input("请输入学生姓名:")
            else:
                print("您的输入有误,请重新输入!")
                search()  # 重新查询
            with open(filename, 'r') as file:  # 打开文件
                student = file.readlines()  # 读取全部内容
                for list in student:
                    d = dict(eval(list))  # 字符串转字典
                    if id is not "":  # 判断是否按ID查
                        if d['id'] == id:
                            student_query.append(d)  # 将找到的学生信息保存到列表中
                    elif name is not "":  # 判断是否按姓名查
                        if d['name'] == name:
                            student_query.append(d)  # 将找到的学生信息保存到列表中
                show_student(student_query)  # 显示查询结果
                student_query.clear()  # 清空列表
                inputMark = input("是否继续查询?(y/n):")
                if inputMark == "y":
                    mark = True
                else:
                    mark = False
        else:
            print("暂未保存数据信息...")
            return
 
 
'''3 删除学生成绩信息'''
 
 
def delete():
    mark = True  # 标记是否循环
    while mark:
        studentId = input("请输入要删除的学生ID:")
        if studentId is not "":  # 判断要删除的学生是否存在
            if os.path.exists(filename):  # 判断文件是否存在
                with open(filename, 'r') as rfile:  # 打开文件
                    student_old = rfile.readlines()  # 读取全部内容
            else:
                student_old = []
            ifdel = False  # 标记是否删除
            if student_old:  # 如果存在学生信息
                with open(filename, 'w') as wfile:  # 以写方式打开文件
                    d = {}  # 定义空字典
                    for list in student_old:
                        d = dict(eval(list))  # 字符串转字典
                        if d['id'] != studentId:
                            wfile.write(str(d) + "\n")  # 将一条学生信息写入文件
                        else:
                            ifdel = True  # 标记已经删除
                    if ifdel:
                        print("ID为 %s 的学生信息已经被删除..." % studentId)
                    else:
                        print("没有找到ID为 %s 的学生信息..." % studentId)
            else:  # 不存在学生信息
                print("无学生信息...")
                break  # 退出循环
            show()  # 显示全部学生信息
            inputMark = input("是否继续删除?(y/n):")
            if inputMark == "y":
                mark = True  # 继续删除
            else:
                mark = False  # 退出删除学生信息功能
 
 
'''4 修改学生成绩信息'''
 
 
def modify():
    show()  # 显示全部学生信息
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
    else:
        return
    studentid = input("请输入要修改的学生ID:")
    with open(filename, "w") as wfile:  # 以写模式打开文件
        for student in student_old:
            d = dict(eval(student))  # 字符串转字典
            if d["id"] == studentid:  # 是否为要修改的学生
                print("找到了这名学生,可以修改他的信息!")
                while True:  # 输入要修改的信息
                    try:
                        d["name"] = input("请输入姓名:")
                        d["english"] = int(input("请输入英语成绩:"))
                        d["python"] = int(input("请输入Python成绩:"))
                        d["c"] = int(input("请输入C语言成绩:"))
                    except:
                        print("您的输入有误,请重新输入。")
                    else:
                        break  # 跳出循环
                student = str(d)  # 将字典转换为字符串
                wfile.write(student + "\n")   # 将修改的信息写入到文件
                print("修改成功!")
            else:
                wfile.write(student)  # 将未修改的信息写入到文件
    mark = input("是否继续修改其他学生信息?(y/n):")
    if mark == "y":
        modify()  # 重新执行修改操作
 
 
'''5 排序'''
 
 
def sort():
    show()  # 显示全部学生信息
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as file:  # 打开文件
            student_old = file.readlines()  # 读取全部内容
            student_new = []
        for list in student_old:
            d = dict(eval(list))  # 字符串转字典
            student_new.append(d)  # 将转换后的字典添加到列表中
    else:
        return
    ascORdesc = input("请选择(0升序;1降序):")
    if ascORdesc == "0":  # 按升序排序
        ascORdescBool = False           # 标记变量,为False表示升序排序
    elif ascORdesc == "1":  # 按降序排序
        ascORdescBool = True          # 标记变量,为True表示降序排序
    else:
        print("您的输入有误,请重新输入!")
        sort()  
    mode = input("请选择排序方式(1按英语成绩排序;2按Python成绩排序;3按C语言成绩排序;0按总成绩排序):")
    if mode == "1":  # 按英语成绩排序
        student_new.sort(key=lambda x: x["english"], reverse=ascORdescBool)
    elif mode == "2":  # 按Python成绩排序
        student_new.sort(key=lambda x: x["python"], reverse=ascORdescBool)
    elif mode == "3":  # 按C语言成绩排序
        student_new.sort(key=lambda x: x["c"], reverse=ascORdescBool)
    elif mode == "0":  # 按总成绩排序
        student_new.sort(key=lambda x: x["english"] + x["python"] + x["c"], reverse=ascORdescBool)
    else:
        print("您的输入有误,请重新输入!")
        sort()
    show_student(student_new)  # 显示排序结果
 
 
''' 6 统计学生总数'''
 
 
def total():
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
            if student_old:
                print("一共有 %d 名学生!" % len(student_old))
            else:
                print("还没有录入学生信息!")
    else:
        print("暂未保存数据信息...")
 
 
''' 7 显示所有学生信息 '''
 
 
def show():
    student_new = []
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
        for list in student_old:
            student_new.append(eval(list))  # 将找到的学生信息保存到列表中
        if student_new:
            show_student(student_new)
    else:
        print("暂未保存数据信息...")
 
 
# 将保存在列表中的学生信息显示出来
def show_student(studentList):
    if not studentList:
        print("(o@.@o) 无数据信息 (o@.@o) \n")
        return
    format_title = "{:^6}{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^10}"
    print(format_title.format("ID", "名字", "英语成绩", "Python成绩", "C语言成绩", "总成绩"))
    format_data = "{:^6}{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}"
    for info in studentList:
        print(format_data.format(info.get("id"), info.get("name"), str(info.get("english")), str(info.get("python")),
                                 str(info.get("c")),
                                 str(info.get("english") + info.get("python") + info.get("c")).center(12)))
 
 
if __name__ == "__main__":
    main()

简单实现web查询sqlite3数据库

uupython阅读(409)

1.填充数据

import sqlite3
# 连接到数据库(如果数据库不存在,则会创建一个新的数据库)
conn = sqlite3.connect(r'C:\Users\Administrator\database.sqlite3')
 
# 创建游标对象
cursor = conn.cursor()
 
# 创建renyuan表
cursor.execute('''CREATE TABLE renyuan (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT,
                    age INTEGER,
                    gender TEXT,
                    wealth REAL,
                    source TEXT,
                    industry TEXT,
                    country TEXT,
                    rank INTEGER
                )''')
 
# 插入数据
data = [
    ('马云', 57, '男', 450, '阿里巴巴', '电子商务', '中国', 1),
    ('马化腾', 50, '男', 440, '腾讯', '互联网', '中国', 2),
    ('许家印', 63, '男', 430, '恒大集团', '房地产', '中国', 3),
    ('杨惠妍', 40, '女', 410, '中国恒大', '房地产', '中国', 4),
    ('张一鸣', 39, '男', 400, '字节跳动', '互联网', '中国', 5),
    ('王健林', 67, '男', 390, '万达集团', '房地产', '中国', 6),
    ('王卫', 59, '男', 380, '中国联通', '电信', '中国', 7),
    ('雷军', 53, '男', 370, '小米', '电子产品', '中国', 8),
    ('刘强东', 48, '男', 360, '京东', '电子商务', '中国', 9),
    ('丁磊', 49, '男', 350, '网易', '互联网', '中国', 10),
    ('宗庆后', 75, '男', 340, '娃哈哈', '饮料', '中国', 11),
    ('许荣茂', 64, '男', 330, '恒力集团', '化工', '中国', 12),
    ('刘永好', 71, '男', 320, '碧桂园', '房地产', '中国', 13),
    ('孙正义', 64, '男', 310, '软银', '投资', '中国', 14),
    ('孙宏斌', 59, '男', 300, '乐视网', '互联网', '中国', 15),
    ('潘石屹', 59, '男', 290, 'SOHO中国', '房地产', '中国', 16),
    ('许家标', 62, '男', 280, '恒大集团', '房地产', '中国', 17),
    ('姚振华', 59, '男', 270, '中国国电集团', '能源', '中国', 18),
    ('李彦宏', 53, '男', 260, '百度', '互联网', '中国', 19),
    ('王石', 73, '男', 250, '万科企业', '房地产', '中国', 20),
]
 
cursor.executemany('INSERT INTO renyuan (name, age, gender, wealth, source, industry, country, rank) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', data)
 
# 提交事务
conn.commit()
 
# 关闭游标和数据库连接
cursor.close()
conn.close()

2.显示及查询数据

import sqlite3
from flask import Flask, render_template_string, request, jsonify
import threading
import tkinter as tk
import time
import os
import signal
 
# 数据库路径
DB_PATH = "C:/Users/Administrator/database.sqlite3"
 
# 创建Flask应用
app = Flask(__name__)
 
# 全局变量,用于判断Flask进程的运行状态
running = False
 
# 创建Tkinter窗口
window = tk.Tk()
window.title("数据库查询工具")
window.geometry("320x320")
 
# 文字状态指示控件
status_label = tk.Label(window, text="已停止", font=("Arial", 12))
status_label.pack(pady=20)
 
# 切换运行/停止按钮点击事件
def toggle_flask():
    global running
    if running:
        # 停止Flask进程
        os.kill(os.getpid(), signal.SIGINT)
        running = False
        status_label.config(text="已停止")
    else:
        # 启动Flask进程
        threading.Thread(target=start_flask).start()
 
# 切换运行/停止按钮
toggle_button = tk.Button(window, text="切换运行/停止", command=toggle_flask)
toggle_button.pack(pady=10)
 
# 退出程序按钮点击事件
def exit_program():
    # 关闭Flask进程
    os.kill(os.getpid(), signal.SIGINT)
    time.sleep(1)
    # 关闭Tkinter窗口
    window.destroy()
 
# 退出程序按钮
exit_button = tk.Button(window, text="退出程序", command=exit_program)
exit_button.pack(pady=10)
 
# 启动Flask进程的函数
def start_flask():
    global running
    running = True
    status_label.config(text="正在运行")
    app.run()
 
# Flask路由:根路径
@app.route('/')
def index():
    table_data = get_all_data()
    columns = get_table_columns()
    return render_template_string('''
        <h1>数据库查询工具</h1>
        <h2>renyuan数据表</h2>
        <table border="1">
            <thead>
                <tr>
                    {% for column in columns %}
                    <th>{{ column }}</th>
                    {% endfor %}
                </tr>
            </thead>
            <tbody>
                {% for row in table_data %}
                <tr>
                    {% for value in row.values() %}
                    <td>{{ value }}</td>
                    {% endfor %}
                </tr>
                {% endfor %}
            </tbody>
        </table>
        <h2>精确查询</h2>
        <select id="column">
            <option value="">选择列名</option>
            {% for column in columns %}
            <option value="{{ column }}">{{ column }}</option>
            {% endfor %}
        </select>
        <input type="text" id="search" placeholder="输入查询信息">
        <button onclick="search()">查询</button>
        <table id="search-results" border="1">
            <thead>
                <tr>
                    {% for column in columns %}
                    <th>{{ column }}</th>
                    {% endfor %}
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
        <script>
            function search() {
                var column = $("#column").val();
                var search = $("#search").val();
                $.post("/search", {column: column, search: search}, function(data) {
                    var tbody = $("#search-results tbody");
                    tbody.empty();
                    $.each(data, function(index, row) {
                        var tr = $("<tr></tr>");
                        {% for column in columns %}
                        tr.append("<td>" + row["{{ column }}"] + "</td>");
                        {% endfor %}
                        tbody.append(tr);
                    });
                });
            }
        </script>
    ''', table_data=table_data, columns=columns)
 
# Flask路由:精确查询
@app.route('/search', methods=['POST'])
def search():
    column = request.form['column']
    search = request.form['search']
    data = search_data(column, search)
    return jsonify(data)
 
# 查询数据库中的所有数据
def get_all_data():
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM renyuan")
    rows = cursor.fetchall()
    columns = [column[0] for column in cursor.description]
    data = [dict(zip(columns, row)) for row in rows]
    conn.close()
    return data
 
# 获取数据库表的列名
def get_table_columns():
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute("PRAGMA table_info(renyuan)")
    columns = [column[1] for column in cursor.fetchall()]
    conn.close()
    return columns
 
# 根据列名和查询信息进行精确查询
def search_data(column, search):
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute(f"SELECT * FROM renyuan WHERE {column}=?", (search,))
    rows = cursor.fetchall()
    columns = [column[0] for column in cursor.description]
    data = [dict(zip(columns, row)) for row in rows]
    conn.close()
    return data
 
# 运行Tkinter窗口主循环
window.mainloop()

爬取图虫网的美女

uupython阅读(410)

这段代码是一个简单的Python脚本,用于从图虫网站下载图片。图虫网站(Tuchong)是一个以摄影作品为主的社交平台。代码通过爬取图虫网站上的帖子信息,获取每个帖子中的图片链接,然后使用多线程方式下载这些图片。

以下是代码的主要功能和流程:

  1. 导入所需的模块:ostimerequestsreconcurrent.futures.ThreadPoolExecutor
  2. 定义函数normalize_directory_name(name):用于处理目录名称,将非法字符替换为空格,并限制长度为100个字符。
  3. 定义函数download_image(image_info):用于下载图片。它从传入的image_info中提取用户ID和图片ID,构建图片的URL,然后使用requests.get()发送HTTP请求获取图片内容。最后,返回图片ID和图片数据。
  4. 在主循环中,从1到98的范围内,构建URL来获取图虫网站上的帖子信息。通过发送HTTP请求,获取每一页的帖子列表。
  5. 使用ThreadPoolExecutor来并行下载每个帖子中的图片。首先,构建一个待执行任务列表futures,每个任务都是一个executor.submit()调用,传入download_image函数和每个帖子中的图片信息。然后,通过迭代futures列表,使用future.result()获取下载的图片数据和图片ID。
  6. 对每个帖子,获取帖子中的图片列表,如果图片列表长度大于1,遍历图片列表,找到与下载的图片ID匹配的图片信息。获取帖子的标题作为文件夹名,并调用normalize_directory_name()来处理文件夹名。然后,构建图片的保存路径,如果文件夹不存在则创建文件夹,并将下载的图片内容保存到相应路径。

代码的目标是下载图虫网站上的图片,每个帖子可能包含多张图片,代码在下载时将图片保存在以帖子标题为名的文件夹中。注意,多线程下载可以提高效率,但也需要考虑线程安全问题和服务器访问频率限制。在使用此代码时,请务必遵循网站的使用规定和法律法规。

import os
import time
import requests
import re
from concurrent.futures import ThreadPoolExecutor
 
# 处理目录非法字符
def normalize_directory_name(name):
    # 使用正则表达式替换非法字符为空格
    cleaned_name = re.sub(r'[\\/:*?"<>|]', ' ', name)
    # 去除多余的空格,并限制长度为100个字符
    normalized_name = re.sub(r'\s+', ' ', cleaned_name).strip()[:100]
    return normalized_name
 
def download_image(image_info):
    user_id = image_info['user_id']
    img_id_str = image_info['img_id_str']
    img_url = f'https://photo.tuchong.com/{user_id}/f/{img_id_str}.webp'
    image_data = requests.get(url=img_url, proxies=None).content
    return img_id_str, image_data
 
for k in range(1, 99):
    url = f'https://tuchong.com/rest/tags/%E7%BE%8E%E5%A5%B3/posts?page={k}&count=20&order=weekly&before_timestamp='
 
    response = requests.get(url=url) 
    json_data = response.json()
 
    post_list = json_data['postList']
 
    with ThreadPoolExecutor() as executor:
        futures = [executor.submit(download_image, image_info) for post in post_list for image_info in post.get('images', [])]
 
        for future in futures:
            img_id_str, image_data = future.result()
 
            # 获取帖子标题
            for post in post_list:
                images = post.get('images', [])
                if len(images) <= 1:
                    continue
                if any(image_info['img_id_str'] == img_id_str for image_info in images):
                    title = post['title']
                    if not title:  # 如果标题为空,则用用户ID替代
                        title = post['author_id']
                    title = normalize_directory_name(title)
                    image_dir = f'G:/tuchongspider/{title}'
                    if not os.path.exists(image_dir):
                        os.makedirs(image_dir)
 
                    image_path = f'{image_dir}/{title}-{img_id_str}.webp'
                    with open(image_path, 'wb') as f:
                        f.write(image_data)
 
                    print(f'Downloaded {img_id_str}.webp')
                    break

爬小姐姐的源码

uupython阅读(498)

这段代码实现了一个多线程图片下载工具,用于从网站 https://www.xiezhen.xyz/ 下载漫画图片。代码中使用了requests库来进行网络请求,lxml库来解析HTML,以及concurrent.futures.ThreadPoolExecutor来实现多线程下载。

以下是代码的主要功能和流程:

  1. 导入所需的模块:timerequestsetree(来自lxml库)、osconcurrent.futures
  2. 定义函数download_image(url, img_path):用于下载单张图片。它接受图片的URL和保存路径作为参数,发送HTTP请求并将图片内容保存到指定路径。
  3. 定义函数process_page(page):用于处理每一页漫画图片。它首先根据页面号构建URL,然后发送HTTP请求获取页面内容。接着,从页面中提取每篇文章(漫画章节)的链接,进入每篇文章并提取漫画图片的URL。随后,创建相应的文件夹,使用ThreadPoolExecutor来并行下载漫画图片,将下载的图片保存到相应的文件夹中。
  4. __name__ == '__main__'部分,使用ThreadPoolExecutor来并行处理不同页面的漫画图片。首先,通过循环迭代的方式,创建多个线程来处理每一页漫画。然后,使用concurrent.futures.as_completed来等待并处理这些线程的结果。

需要注意的是,多线程下载可以显著提高下载效率,但也要注意在使用多线程时避免出现线程安全问题。此外,代码中的延时time.sleep(0.5)可能是为了避免频繁的网络请求,减轻服务器负担。如果你想要运行这段代码,确保你已经安装了requestslxml等相关的库。

import time
import requests
from lxml import etree
import os
import concurrent.futures
 
def download_image(url, img_path):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    response = requests.get(url, headers=headers)
    img_name = url.split('/')[-1]
    with open(os.path.join(img_path, img_name), 'wb') as f:
        f.write(response.content)
        print(f'图片:{img_path}' + '/' + f'{img_name}下载完成!')
 
def process_page(page):
    url = f'https://www.xiezhen.xyz/page/{page}'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    response = requests.get(url, headers=headers)
    html = etree.HTML(response.content)
    mail_url = html.xpath('//div[@class="excerpts"]/article/a/@href')
    for url in mail_url:
        response = requests.get(url, headers=headers)
        html = etree.HTML(response.content)
        sub_url = html.xpath('//article/p/img')
        img_title = html.xpath('//title/text()')[0].split('-')[0]
        img_path = f'J:/xiezhen/{img_title}'
        if not os.path.exists(img_path):
            os.makedirs(img_path)
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = []
            for s_url in sub_url:
                img_url = s_url.attrib['src']
                futures.append(executor.submit(download_image, img_url, img_path))
            for future in concurrent.futures.as_completed(futures):
                pass
        time.sleep(0.5)
 
if __name__ == '__main__':
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for page in range(1, 573):
            futures.append(executor.submit(process_page, page))
        for future in concurrent.futures.as_completed(futures):
            pass

[GUI]获取汉字笔顺并形成笔顺图片

uupython阅读(656)

这段代码是一个Python脚本,它是一个用于生成汉字笔顺和相关信息的工具。它使用了tkinter库来创建一个简单的图形用户界面(GUI),用户可以在界面上输入汉字,选择颜色等选项,然后生成相应的汉字笔顺和相关信息。以下是这段代码的主要功能和流程:

  1. 导入所需的模块:
    • re: 用于正则表达式操作
    • urllib.requesturllib.parse: 用于进行网页请求和URL编码
    • time: 用于添加延时
    • os: 用于文件和文件夹操作
    • lxml.etree: 用于解析HTML/XML文档
    • pandas: 用于数据处理和Excel操作
    • openpyxl: 用于处理Excel文件
    • cairosvg: 用于将SVG路径转换为PNG图片
    • tkinter: 用于创建GUI界面
  2. 创建了一个类SelectPage,该类包含了GUI界面的创建和各种用户交互的函数。
  3. createWidgets函数中,使用tkinter库创建了一个GUI界面,包括选择字体颜色、最后一笔颜色、选择汉字文件和保存文件夹等功能。
  4. craw_pinyin函数用于获取汉字的拼音信息。
  5. ChangeSVG2png函数用于将SVG路径转换为PNG图片,并根据用户选择的颜色进行着色。
  6. craw函数用于从百度网站获取汉字的各种详细信息,如拼音、笔画数、汉字动画、读音地址、字谜、基础释义等。
  7. createBiShun函数用于批量生成汉字的笔顺和相关信息,并将结果写入到Excel文件中。
  8. if __name__ == '__main__':部分初始化了一个tkinter窗口,并创建了SelectPage类的实例来启动程序。

需要注意的是,这段代码中使用了一些外部库和依赖项,如果你想运行这段代码,确保你已经安装了这些依赖项。另外,代码中有一些中文注释,可能在部分编程环境中需要设置正确的编码方式来确保注释显示正常。

# -!- coding: utf-8 -!-
import re
import urllib.request
import urllib.parse
import time
import os
 
from lxml import etree
import pandas as pd
from openpyxl import load_workbook
 
#将SVG路径转换为png图片
from cairosvg import svg2png
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import askdirectory
from tkinter.filedialog import asksaveasfilename
from tkinter.ttk import *
 
OUTPUTADDRESS = 'D:/汉字笔画/'
 
def select_db_file(self):
    db_file = askopenfilename(title="请选择汉字文件",filetypes=[('xlsx', '*.xlsx')])
    self.db.set(db_file)
 
def select_save_file(self):
    save_directory = askdirectory(initialdir=OUTPUTADDRESS)
    self.f.set(save_directory+ '/')
 
class SelectPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁子界面
        super(SelectPage, self).__init__()
        self.createWidgets()
 
 
    def createWidgets(self):
        # 设置界面
        self.window = tk.Tk()  # 实例化object,建立窗口window
        self.window.winfo_toplevel()
        self.window.title('笔顺生成工具------Design By xxx')
 
        # 字体颜色
        font_color_label = Label(self.window, font=('微软雅黑', 10), text='字体颜色', justify='right')
        font_color_label.grid(row=1,column=1,padx=(2,0),pady=(2,0),sticky='WE')
 
        font_color_label2 = Label(self.window, font=('微软雅黑', 6), text='(黑色:#000000;灰色:#B8B8B8)', justify='right',background='lightskyblue')
        font_color_label2.grid(row=1, column=2, padx=(2, 0), pady=(2, 0), sticky='WE')
 
        self.window.font_color = tk.StringVar(value='#B8B8B8')
        font_color_entry = Entry(self.window, width=80, textvariable=self.window.font_color)
        font_color_entry.grid(row=1, column=3, padx=3, pady=3, sticky='WE')
 
        # 字体最后一笔颜色
        font_color_last_label = Label(self.window, font=('微软雅黑', 10), text='最后一笔颜色', justify='right')
        font_color_last_label.grid(row=2, column=1, padx=(2,0), pady=(2,0), sticky='WE')
 
        font_color_last_label2 = Label(self.window, font=('微软雅黑', 6), text='(白色:#FFFFFF;红色:#FF1111)',justify='right',background='lightskyblue')
        font_color_last_label2.grid(row=2, column=2, padx=(2, 0), pady=(2, 0), sticky='WE')
 
        self.window.font_color_last = tk.StringVar(value='#B8B8B8')
        font_color_last_entry = Entry(self.window, width=80, textvariable=self.window.font_color_last)
        font_color_last_entry.grid(row=2, column=3, padx=3, pady=3, sticky='WE')
 
        # 需要爬取信息的汉字文件路径
        self.window.db = tk.StringVar()
        db_select = Button(self.window, text='汉字文件',command=lambda:select_db_file(self.window))
        db_select.grid(row=3,column=1,columnspan=2 ,sticky='W',padx=(2,0),pady=(2,0))
 
        ExcelFile_path = Entry(self.window,width=80,textvariable = self.window.db)
        ExcelFile_path['state'] = 'readonly'
        ExcelFile_path.grid(row=3,column=3,padx=3,pady=3,sticky='WE')
 
        # 需要保存汉字信息的文件夹路径
        self.window.f = tk.StringVar()
        save_path = Button(self.window, text='笔顺保存地址',command=lambda:select_save_file(self.window))
        save_path.grid(row=4,column=1,columnspan=2, sticky='W',padx=(2,0),pady=(2,0))
 
        ExcelOutputFile_path = Entry(self.window,width=80,textvariable = self.window.f)
        ExcelOutputFile_path['state'] = 'readonly'
        ExcelOutputFile_path.grid(row=4, column=3,padx=3,pady=3,sticky='WE')
 
        # 启动生成笔顺
        ExcelFile_sheetName = '生字表(一上)'
        create_btn = Button(self.window, text='生成笔顺',command=lambda: createBiShun(self.window,self.window.db.get(),ExcelFile_sheetName,self.window.f.get()))
        create_btn.grid(row=5,column=1,columnspan=3,pady=(0,2))
        self.window.columnconfigure(2, weight=1)
        self.window.mainloop()
 
    def get_font_color(self):
        return self.window.font_color.get()
 
# 生成完整字体:读取汉字的详细信息,从百度网站读取信息
def ChineseChangeSVG2png(windows,svg_path,chinese):
    #1. 根据路径生成svg_code
    # style="fill: #FFFFFF ;黑色字体
    outputpath = OUTPUTADDRESS + chinese
    svg_output = {
        'width':'83px',
        'height':'83px',
        'xmlns':'http://www.w3.org/2000/svg',
        "font_color": "#000000",  # 黑色
        "font_color_last": "#FF1111",  # 红色
        "output_address": outputpath,
        "output_filename": ''
    }
 
    if not os.path.exists(outputpath):#为每个汉字创建文件夹
        os.mkdir(outputpath)
 
    svg_code = []
    svg_code_temp = '<svg style="width: ' + svg_output['width'] +'; height:' + svg_output['height'] +';" xmlns="' + svg_output['xmlns'] +'">'
    svg_code.append(svg_code_temp)
    svg_code_temp = '    <g transform="translate(3, 70) scale(0.07, -0.07)">'
    svg_code.append(svg_code_temp)
    # 加入路径代码
    for outputpath_perstep in svg_path:
        svg_code_temp = '        <path d="'+outputpath_perstep+'" style="fill: '+ svg_output['font_color'] +';"></path>'
        svg_code.append(svg_code_temp)
    svg_code_temp ='    </g>'
    svg_code.append(svg_code_temp)
    svg_code_temp = '</svg>'
    svg_code.append(svg_code_temp)
    # 输出png图片
    svgcode = '\n'.join(svg_code)
    svg_output['output_filename'] = svg_output['output_address'] + '/' + chinese + '0.png' # 完整汉字的文件以0结尾
    try:
        svg2png(bytestring=svgcode, write_to=svg_output['output_filename'])
    except Exception as e:
        print('error:' + e)
 
def craw_pinyin(chinese):
    # 获得汉字的拼音
    url = 'http://hanyu.baidu.com/s?wd=' + urllib.parse.quote(chinese) + '&ptype=zici'
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'
    }
    serverError = True
    chinese_details = {
        "chinese": chinese,  # 汉字
        "pinyin": "",  # 拼音
    }
    while serverError:
        try:
            request = urllib.request.Request(url, headers=header)
            reponse = urllib.request.urlopen(request).read()
            html = str(reponse)
            web_html = etree.HTML(str(reponse, 'utf-8'))
 
            # 取得拼音
            try:
                pinyin = web_html.xpath('//div[@id="pinyin"]')[0]
                pinyin_text = '、'.join(pinyin.xpath('span/b/text()'))
                chinese_details['pinyin'] = pinyin_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:pinyin")
 
            serverError = False
 
        except Exception as e:
            print(chinese + 'server error')
            time.sleep(2)
    print('读取汉字信息:' + chinese, pinyin_text)
    return chinese_details
 
 
# 读取汉字的详细信息,从百度网站读取信息
def ChangeSVG2png(windows,svg_path,chinese):
    #1. 根据路径生成svg_code
    # style="fill: #B8B8B8 ;灰色字体
    # style="fill: #FF1111 ;红色字体
    outputpath = OUTPUTADDRESS + chinese
    svg_output = {
        'width':'83px',
        'height':'83px',
        'xmlns':'http://www.w3.org/2000/svg',
        "font_color": "#B8B8B8",  # 灰色
        "font_color_last": "#FF1111",  # 红色
        "output_address": outputpath,
        "output_filename": ''
    }
 
    if not os.path.exists(outputpath):#为每个汉字创建文件夹
        os.mkdir(outputpath)
 
    svg_code = []
    svg_code_temp = '<svg style="width: ' + svg_output['width'] +'; height:' + svg_output['height'] +';" xmlns="' + svg_output['xmlns'] +'">'
    svg_code.append(svg_code_temp)
    svg_code_temp = '    <g transform="translate(3, 70) scale(0.07, -0.07)">'
    svg_code.append(svg_code_temp)
    # 加入路径代码
    for outputpath_perstep in svg_path:
        if svg_path.index(outputpath_perstep)+1 < len(svg_path):#中间笔画的颜色
            # svg_code_temp = '        <path d="'+outputpath_perstep+'" style="fill: '+ svg_output['font_color'] +';"></path>'
            svg_code_temp = '        <path d="' + outputpath_perstep + '" style="fill: ' + windows.font_color.get() + ';"></path>'
        else:#最后一笔的颜色
            # svg_code_temp = '        <path d="' + outputpath_perstep + '" style="fill: ' + svg_output['font_color_last'] + ';"></path>' # 红色
            # svg_code_temp = '        <path d="' + outputpath_perstep + '" style="fill: ' + svg_output['font_color'] + ';"></path>' # 灰色
            svg_code_temp = '        <path d="' + outputpath_perstep + '" style="fill: ' + windows.font_color_last.get() + ';"></path>'  # 灰色
        svg_code.append(svg_code_temp)
    svg_code_temp ='    </g>'
    svg_code.append(svg_code_temp)
    svg_code_temp = '</svg>'
    svg_code.append(svg_code_temp)
    # 输出png图片
    svgcode = '\n'.join(svg_code)
    svg_output['output_filename'] = svg_output['output_address'] + '/' + chinese + str(len(svg_path)) + '.png'
    try:
        svg2png(bytestring=svgcode, write_to=svg_output['output_filename'])
    except Exception as e:
        print('error:' + e)
 
def craw_pinyin(chinese):
    # 获得汉字的拼音
    url = 'http://hanyu.baidu.com/s?wd=' + urllib.parse.quote(chinese) + '&ptype=zici'
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'
    }
    serverError = True
    chinese_details = {
        "chinese": chinese,  # 汉字
        "pinyin": "",  # 拼音
    }
    while serverError:
        try:
            request = urllib.request.Request(url, headers=header)
            reponse = urllib.request.urlopen(request).read()
            html = str(reponse)
            web_html = etree.HTML(str(reponse, 'utf-8'))
 
            # 取得拼音
            try:
                pinyin = web_html.xpath('//div[@id="pinyin"]')[0]
                pinyin_text = '、'.join(pinyin.xpath('span/b/text()'))
                chinese_details['pinyin'] = pinyin_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:pinyin")
 
            serverError = False
 
        except Exception as e:
            print(chinese + 'server error')
            time.sleep(2)
    print('读取汉字信息:' + chinese, pinyin_text)
    return chinese_details
 
 
 
def craw(windows,chinese,ExcelOutputFile_path):
    url = 'http://hanyu.baidu.com/s?wd=' + urllib.parse.quote(chinese) + '&ptype=zici'
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'
    }
    serverError = True
    chinese_details = {
        "chinese": chinese,# 汉字
        "pinyin": "", # 拼音
        "stroke_count":"", # 笔画数
        "img_address": "",# 笔顺动画
        "mp3_address": "",# 发音地址
        "zimi":"",# 字谜
        "basicmean":"", # 基本释义
        "zuci": "", # 相关词组
        "synonym":"", # 近义词
        "antonym":"", # 反义词
        "bishun_svg": "",  # 笔顺SVG路径
        "baikemean":"" #百科释义
    }
    while serverError:
        try:
 
            request = urllib.request.Request(url, headers=header)
            reponse = urllib.request.urlopen(request).read()
            html = str(reponse)
 
            web_html = etree.HTML(str(reponse,'utf-8'))
 
            if not os.path.exists(OUTPUTADDRESS + chinese + '/'):  # 为每个汉字创建文件夹
                os.mkdir(OUTPUTADDRESS + chinese + '/')
 
            # 取得拼音
            try:
                pinyin = web_html.xpath('//div[@id="pinyin"]')[0]
                pinyin_text = '、'.join(pinyin.xpath('span/b/text()'))
                chinese_details['pinyin'] = pinyin_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:pinyin")
 
            # 取得笔画数
            try:
                stroke_count = web_html.xpath('//li[@id="stroke_count"]')[0]
                stroke_count_text = stroke_count.xpath('span')[0].text
                chinese_details['stroke_count'] = stroke_count_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:pinyin")
 
            #取得汉字动画和汉字读音
            try:
                imgs = re.compile('data-gif="(.+?\.gif)"').findall(html)# 获取汉字动图
                mp3s = re.compile('url="(.+?\.mp3)"').findall(html)# 获取汉字读音
 
                for img,mp3 in zip(imgs,mp3s):
                    imagename = ExcelOutputFile_path +  chinese + '/' + chinese + '.gif'
                    imageurl = img
                    chinese_details['img_address'] = imageurl
                    mp3name = ExcelOutputFile_path + chinese + '/' + chinese + '.mp3'
                    mp3url = mp3
                    chinese_details['mp3_address'] = mp3url
                    # 下载动画和读音文件
                    try:
                        urllib.request.urlretrieve(imageurl, filename=imagename)
                        urllib.request.urlretrieve(mp3url, filename=mp3name)
                    except Exception as e:
                        print(chinese + ' failure')
            except Exception as e:
                print("无法获得" + chinese + "的属性:img,mp3")
 
            #取得字谜
            try:
                zimi = web_html.xpath('//div[@id="miyu-wrapper"]')[0]
                zimi_text = ' '.join(zimi.xpath('div/p/text()'))
                chinese_details['zimi'] = zimi_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:zimi")
 
            #取得基本释义
            try:
                basicmean = web_html.xpath('//div[@id="basicmean-wrapper"]')[0]
                basicmean_text = '。'.join(basicmean.xpath('div/dl/dd/p/text()'))
                chinese_details['basicmean'] = basicmean_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:basicmean")
 
            # 取得相关组词
            try:
                zuci = web_html.xpath('//div[@id="zuci-wrapper"]')[0]
                zuci_text = '、'.join(zuci.xpath('div/a/text()')[0:-1])
                chinese_details['zuci'] = zuci_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:zuci")
 
            # 取得近义词
            try:
                synonym = web_html.xpath('//div[@id="synonym"]')[0]
                synonym_text = '、'.join(synonym.xpath('div/a/text()'))
                chinese_details['synonym'] = synonym_text
            except Exception as e:
                # print("无法获得" + chinese + "的属性:antonym")
                pass
 
            # 取得反义词antonym
            try:
                antonym = web_html.xpath('//div[@id="antonym"]')[0]
                antonym_text = '、'.join(antonym.xpath('div/a/text()'))
                chinese_details['antonym'] = antonym_text
            except Exception as e:
                # print("无法获得" + chinese + "的属性:antonym")
                pass
 
            # 取得SVG路径
            try:
                bishun = web_html.xpath('//div[@class="word-stroke-wrap"]')[0]
                bishun_svg = [x.get('d') for x in bishun.xpath('./div[1]/div/div/svg/g/path')]
                chinese_details['bishun_svg'] = bishun_svg
                svgpaths = bishun_svg[0:-1]
                svgpath_perstep = []
                for svgpath in svgpaths:
                    svgpath_perstep.append(svgpath)
                    ChangeSVG2png(windows, svgpath_perstep, chinese)
 
                ChineseChangeSVG2png(windows, svgpaths, chinese)
            except Exception as e:
                print("无法获得" + chinese + "的属性:bishun")
 
            # 取得百科释义
            try:
                baikemean = web_html.xpath('//div[@id="baike-wrapper"]')[0]
                baikemean_text = str(baikemean.xpath('normalize-space(div[2]/p/text())'))
                chinese_details['baikemean'] = baikemean_text
            except Exception as e:
                print("无法获得" + chinese + "的属性:baikemean")
 
            serverError = False
        except Exception as e:
            print(chinese + 'server error')
            time.sleep(2)
    print('读取汉字信息:' + chinese,pinyin_text)
    return chinese_details
 
def createBiShun(windows,ExcelFile_path,ExcelFile_sheetName,ExcelOutputFile_path):
    # # ExcelFile_path = r'F:\百度网盘同步空间\BaiduSyncdisk\4. 家庭教育\一年级\汉语拼音练习20221010.xlsx'
    # # ExcelFile_sheetName = '生字表(一上)'
    # df = pd.read_excel(ExcelFile_path, sheet_name=ExcelFile_sheetName, keep_default_na=False, engine='openpyxl')  # sheet_name:None-多个工作表读取
    #
 
    df = pd.read_excel(ExcelFile_path, sheet_name=0, keep_default_na=False,
                       engine='openpyxl')  # sheet_name:None-多个工作表读取;# sheet_name:ExcelFile_sheetName-指定工作表读取
     
    strs = list(df['内容'])
    for st in strs:
        chinese = craw(windows,st,ExcelOutputFile_path)
        df.loc[df['内容'] == st, '拼音'] = chinese['pinyin']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '笔画数'] = chinese['stroke_count']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '笔顺动画地址'] = chinese['img_address']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '读音地址'] = chinese['mp3_address']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '字谜'] = chinese['zimi']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '基础释义'] = chinese['basicmean']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '组词'] = chinese['zuci']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '近义词'] = chinese['synonym']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '反义词'] = chinese['antonym']  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '笔画SVG路径PATH'] = '\n'.join(chinese['bishun_svg'])  # 目标列名为列索引名称,x为目标值,y为更改值
        df.loc[df['内容'] == st, '百科释义'] = chinese['baikemean']  # 目标列名为列索引名称,x为目标值,y为更改值
 
    with pd.ExcelWriter(ExcelFile_path, engin='openpyxl') as writer:
        df.to_excel(writer, sheet_name=ExcelFile_sheetName, index=False)
 
    print("写入完毕")
 
if __name__ == '__main__':
    window = tk.Tk()
    app = SelectPage(window)