自制网页捷径管理程序

文件建立日期: 2024/11/02
最后修订日期: 2024/12/19
相关软件信息:

Win 10 Python 3.12.4

参考文件: None

说明: 所有内容欢迎引用, 只需注明来源及作者, 本文内容如有错误或用词不当, 敬请指正.

自制网页捷径管理程序

在使用Google Chrome浏览器时, 新分页下有十个网页的捷径可使用, 闲来无事就想编写一个程序来作管理这些捷径, 目标如下说明:

  • 使用tkinter库来建立GUI.
  • 可增减捷径, 编辑名称及内容, 可群组, 可群发. 在不想在太复杂的情况来编写, 所以不直接使用GUI来管理捷径, 而是简单地用文字档, 不在程序中来管理, 由用户自行建立修改文字档内容. 为了文字档的格式管理, 选取设定档ini的格式, 调用configparser库来读取内容.
  • 每一小节就是一群捷径, 点击单一名称的捷径, 就可以开启网页; 而点击该群的名称, 可以一次打开该群所有的网页. 为了简单, 所有可以点击的物件都使用Button.
  • 为了美观, 每个捷径名前都会显示该网页的网站图示 Favicon (favorites icon), 通常favicon.ico的檔案是置於Web伺服器的根目錄下的, 无法连上该网站的话, 以一个问号来代表其图示.
  • 以屏幕的长/寛减去程序的长/寛, 除以二, 来作为程序视窗的左上角位置, 将程序视窗置中.

1. 设定档内容 link.ini (置于同目录)

[常用]
PySimpleGUI = https://github.com/PySimpleGUI/PySimpleGUI/issues?q=is%3Aissue+sort%3Aupdated-desc+
StackOverflow = https://stackoverflow.com/search?tab=newest&q=pysimplegui
LearnKu = https://learnku.com/python/c/qa?order=recent
Email = https://outlook.live.com/mail/inbox
Youtube = https://www.youtube.com/results?search_query=%E9%87%A3&sp=EgIIAg%253D%253D
Facebook = https://www.facebook.com/

[生活]
Translation = https://translate.google.com.tw/?hl=zh-TW
Weather = https://www.cwa.gov.tw/V8/C/W/Town/Town.html?TID=6602500
Rain = https://www.rain-alarm.com/
Map = https://www.google.com.tw/maps/@23.546162,120.6402133,8z?hl=zh-TW

[小说]
起点中文网 = https://www.qidian.com/
纵横中文网 = https://m.zongheng.com/
创世中文网 = https://chuangshi.qq.com/
潇湘书院 = https://www.xxsy.net/
17k小说网 = https://h5.17k.com/
没有的1 = 12345
没有的2 = 67890

[其他]
虾皮 = https://shopee.tw/user/notifications/order
百度 = https://www.baidu.com/

2. 使用 configparser 读取 ini文件

from pprint import pprint
import configparser

config_path = "link.ini"
config = configparser.ConfigParser(interpolation=None)  # configparser.RawConfigParser()
config.read(config_path)
pprint(dict(config))
pprint(dict(config['小说']))
{'DEFAULT': <Section: DEFAULT>,
 '其他': <Section: 其他>,
 '小说': <Section: 小说>,
 '常用': <Section: 常用>,
 '生活': <Section: 生活>}
{'17k小说网': 'https://www.cnpp.cn/pinpai/37297.html',
 '创世中文网': 'https://www.cnpp.cn/pinpai/37295.html',
 '潇湘书院': 'https://www.cnpp.cn/pinpai/37300.html',
 '纵横中文网': 'https://www.cnpp.cn/pinpai/37296.html',
 '起点中文网': 'https://www.cnpp.cn/pinpai/37293.html'}

3. 下载网站图示存档

先調用requests.get下载, 使用PIL.Imag.resize转换成32x32的图示, 并使用PIL.ImageTk.PhotoImage将图示转换为tkinter可用的图片. 这里的图片必须要有个参考的变量一直存在, 否则该图示将不会出现.

def download_icon(url):
    base = urlsplit(url)
    url_root = f"{base.scheme}://{base.netloc}//favicon.ico"
    filename = f"{base.scheme}_{base.netloc.replace(".", "_")}_favicon.ico"
    ok = False
    if not Path(filename).exists():
        try:
            response = requests.get(url_root)
            if response.status_code == 200:
                with open(filename, "wb") as f:
                    f.write(response.content)
                ok = True
        except Exception as e:
            pass
    else:
        ok = True
    if not ok:
        filename = "question.png"
    try:
        im = Image.open(filename)
    except:
        im = Image.open("question.png")
    im = im.resize((32, 32))
    return ImageTk.PhotoImage(im)

4. 使用 webbrowser 开启网页

imort webbrowser
webbrowser.open_new_tab(url)

5. 基本的问号图示 question.png (置于同目录)

question.png

6. 程序视窗置中

def move_to_center():
    root.update()
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    win_width = root.winfo_width()
    win_height = root.winfo_height()
    x, y = (screen_width - win_width) // 2, (screen_height - win_height) // 2
    root.geometry(f"+{x}+{y}")

7. 程序执行结果

程序画面

8. 完整的代码 link.py

注: 由于更新代码, 其部份内容可能与前面说明的代码会有些的不同.

import os
import traceback, sys
from tkinter.messagebox import showinfo

def handle_exception(exc_type, exc_value, exc_traceback):
    tb = traceback.TracebackException.from_exception(exc_value)
    message = ''.join(tb.format())
    showinfo("Traceback", message)

sys.excepthook = handle_exception

import requests
import webbrowser
import configparser
import tkinter as tk
from pathlib import Path
from urllib import request
from urllib.parse import urlsplit
from PIL import Image, ImageTk


class Frame(tk.Frame):

    def __init__(self, text, links):
        self.text = text
        self.links = links
        super().__init__(root_frame, bg="black")
        self.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, padx=1, pady=1)
        button = tk.Button(self, text=self.text, font=font, fg=bg, bg=fg, relief=tk.FLAT, command=self.call_all)
        button.pack(side=tk.TOP, fill=tk.X, expand=0, padx=1, pady=1)
        for key, url in self.links.items():
            image = download_icon(url)
            images.append(image)
            button = tk.Button(self, text=" "+key+" ", font=font, relief=tk.FLAT, anchor=tk.W, fg=fg, bg=bg, image=image, compound=tk.LEFT, command=lambda text=key:self.callback(text))
            button.pack(side=tk.TOP, fill=tk.X, expand=0, padx=1, pady=1)

    def callback(self, text):
        url = self.links[text]
        webbrowser.open_new_tab(url)

    def call_all(self):
        for text, url in self.links.items():
            webbrowser.open_new_tab(url)

def move_to_center():
    root.update()
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    win_width = root.winfo_width()
    win_height = root.winfo_height()
    x, y = (screen_width - win_width) // 2, (screen_height - win_height) // 2
    root.geometry(f"+{x}+{y}")

def download_icon(url):
    base = urlsplit(url)
    url_root = f"{base.scheme}://{base.netloc}//favicon.ico"
    filename = f"{base.scheme}_{base.netloc.replace('.', '_')}_favicon.ico"
    ok = False
    if not Path(filename).exists():
        try:
            response = requests.get(url_root)
            if response.status_code == 200:
                with open(filename, "wb") as f:
                    f.write(response.content)
                ok = True
        except Exception as e:
            pass
    else:
        ok = True
    if not ok:
        filename = "question.png"
    try:
        im = Image.open(filename)
    except:
        im = Image.open("question.png")
    im = im.resize((32, 32))
    return ImageTk.PhotoImage(im)

def edit():
    os.popen(config_path)

fg, bg = "#00FF00", "#004000"
font = ("微软正黑体", 16, "bold")

root = tk.Tk()
root.wm_title("Web Browser")
root.configure(background="black")

root_frame = tk.Frame(root, bg="black")
root_frame.pack(padx=2, pady=2)

frames, images = [], []
config_path = "link.ini"
config = configparser.ConfigParser(interpolation=None)  # configparser.RawConfigParser()
config.optionxform = str                                # disable lowercased keys by default
config.read(config_path)

for text in config.sections():
    links = dict(config[text])
    frame = Frame(text, links)
    frames.append(frame)

button = tk.Button(root, text="连结设定档", font=font, fg=bg, bg=fg, command=edit)
button.pack(fill=tk.X)

move_to_center()
root.mainloop()

9. 桌面点击开启

修改附属档名为.pyw, 并设置其默认程序为python\pythonw.exe, 按右键传送到桌面, 建立捷径, 捷径右键选更改图示, 就可以在桌面随时启用.

  1. 本代码未使用多执行绪 multithreading, 所以在开启网页时, GUI 会有停顿现象, 基本上完全不影响使用.
  2. 第一次下载图示, 可能会稍慢出现视窗.
  3. favicon.ico的档案不是置于Web伺服器的根目录下的, 不另外找出應有的图示, 如 <link rel="shortcut icon" href=".../favicon.ico">,将会以问号图示取代.
本作品采用《CC 协议》,转载必须注明作者和本文链接
Jason Yang
讨论数量: 2

py感觉还是跟系统下载的应用结合起来好一些,网页的话做个主页导航就可以了

file

3个月前 评论
Jason990420 (楼主) 3个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!