基于Python和Tkinter的简易浏览器程序研究学习

部署运行你感兴趣的模型镜像

Python浏览器程序(使用Tkinter)

下面是一个使用Python和Tkinter实现的简单浏览器程序,包含了基本的浏览器功能。

import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import tkinter.font as tkfont
from urllib.request import urlopen, Request
from urllib.error import URLError
from urllib.parse import urlparse
import re
import html
import threading

class Browser:
    def __init__(self, root):
        """初始化浏览器主窗口"""
        self.root = root
        self.root.title("Python浏览器")  # 设置窗口标题
        self.root.geometry("1024x768")  # 设置默认窗口大小
        
        # 当前访问的URL
        self.current_url = ""
        # 历史记录列表
        self.history = []
        # 当前历史记录索引
        self.history_index = -1
        
        self.create_widgets()  # 创建界面组件
        self.setup_bindings()  # 设置事件绑定
        
    def create_widgets(self):
        """创建浏览器界面组件"""
        # 创建顶部导航栏框架
        nav_frame = ttk.Frame(self.root)
        nav_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
        
        # 后退按钮
        self.back_button = ttk.Button(nav_frame, text="←", width=3, command=self.go_back)
        self.back_button.pack(side=tk.LEFT, padx=2)
        
        # 前进按钮
        self.forward_button = ttk.Button(nav_frame, text="→", width=3, command=self.go_forward)
        self.forward_button.pack(side=tk.LEFT, padx=2)
        
        # 刷新按钮
        self.refresh_button = ttk.Button(nav_frame, text="↻", width=3, command=self.refresh_page)
        self.refresh_button.pack(side=tk.LEFT, padx=2)
        
        # 主页按钮
        self.home_button = ttk.Button(nav_frame, text="🏠", width=3, command=self.go_home)
        self.home_button.pack(side=tk.LEFT, padx=2)
        
        # 地址输入框
        self.url_entry = ttk.Entry(nav_frame, width=50)
        self.url_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        
        # 访问按钮
        self.go_button = ttk.Button(nav_frame, text="访问", command=self.navigate)
        self.go_button.pack(side=tk.LEFT, padx=2)
        
        # 创建浏览器内容显示区域
        content_frame = ttk.Frame(self.root)
        content_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        
        # 创建文本区域用于显示网页内容(简化版,实际浏览器应使用更复杂的渲染引擎)
        self.content_area = scrolledtext.ScrolledText(
            content_frame, 
            wrap=tk.WORD, 
            state=tk.DISABLED,
            font=tkfont.Font(family="Arial", size=12)
        )
        self.content_area.pack(fill=tk.BOTH, expand=True)
        
        # 创建状态栏
        self.status_bar = ttk.Label(self.root, text="就绪", relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
    def setup_bindings(self):
        """设置事件绑定"""
        # 绑定回车键到地址栏
        self.url_entry.bind("<Return>", lambda event: self.navigate())
        
    def navigate(self):
        """导航到指定URL"""
        url = self.url_entry.get().strip()  # 获取地址栏内容并去除首尾空格
        
        # 如果URL没有协议头,自动添加http://
        if not re.match(r'^https?://', url, re.IGNORECASE):
            url = 'http://' + url
            
        self.current_url = url  # 更新当前URL
        
        # 更新地址栏显示
        self.url_entry.delete(0, tk.END)
        self.url_entry.insert(0, url)
        
        # 添加到历史记录
        if not self.history or self.history[-1] != url:
            self.history.append(url)
            self.history_index = len(self.history) - 1
            
        # 更新按钮状态
        self.update_navigation_buttons()
        
        # 在状态栏显示加载状态
        self.status_bar.config(text=f"正在加载: {url}")
        
        # 在新线程中加载网页,避免界面冻结
        threading.Thread(target=self.load_url, args=(url,), daemon=True).start()
        
    def load_url(self, url):
        """加载URL内容"""
        try:
            # 设置请求头,模拟浏览器访问
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            }
            req = Request(url, headers=headers)
            
            # 打开URL并读取内容
            with urlopen(req, timeout=10) as response:
                content = response.read().decode('utf-8', errors='replace')
                
                # 在主线程中更新UI
                self.root.after(0, self.display_content, content, url)
                
        except Exception as e:
            # 显示错误信息
            error_msg = f"无法加载页面: {str(e)}"
            self.root.after(0, self.show_error, error_msg)
            
    def display_content(self, content, url):
        """显示网页内容(简化版)"""
        # 启用文本区域进行编辑
        self.content_area.config(state=tk.NORMAL)
        self.content_area.delete(1.0, tk.END)
        
        # 提取并显示标题
        title_match = re.search(r'<title>(.*?)</title>', content, re.IGNORECASE)
        if title_match:
            title = html.unescape(title_match.group(1))
            self.content_area.insert(tk.END, f"标题: {title}\n\n")
        
        # 提取并显示正文内容(简化处理)
        # 移除脚本和样式标签
        content = re.sub(r'<script.*?</script>', '', content, flags=re.DOTALL | re.IGNORECASE)
        content = re.sub(r'<style.*?</style>', '', content, flags=re.DOTALL | re.IGNORECASE)
        
        # 提取段落文本
        paragraphs = re.findall(r'<p.*?>(.*?)</p>', content, re.DOTALL | re.IGNORECASE)
        for p in paragraphs:
            # 移除HTML标签
            text = re.sub(r'<.*?>', '', p)
            text = html.unescape(text).strip()
            if text:
                self.content_area.insert(tk.END, text + "\n\n")
        
        # 禁用文本区域编辑
        self.content_area.config(state=tk.DISABLED)
        
        # 更新状态栏
        self.status_bar.config(text=f"已加载: {url}")
        
    def show_error(self, error_msg):
        """显示错误信息"""
        # 启用文本区域进行编辑
        self.content_area.config(state=tk.NORMAL)
        self.content_area.delete(1.0, tk.END)
        self.content_area.insert(tk.END, f"错误: {error_msg}\n\n请检查URL是否正确,或尝试其他网站。")
        # 禁用文本区域编辑
        self.content_area.config(state=tk.DISABLED)
        
        # 更新状态栏
        self.status_bar.config(text=f"错误: {error_msg}")
        
    def go_back(self):
        """导航到历史记录中的上一个页面"""
        if self.history_index > 0:
            self.history_index -= 1
            url = self.history[self.history_index]
            self.url_entry.delete(0, tk.END)
            self.url_entry.insert(0, url)
            self.navigate()
            
    def go_forward(self):
        """导航到历史记录中的下一个页面"""
        if self.history_index < len(self.history) - 1:
            self.history_index += 1
            url = self.history[self.history_index]
            self.url_entry.delete(0, tk.END)
            self.url_entry.insert(0, url)
            self.navigate()
            
    def refresh_page(self):
        """刷新当前页面"""
        if self.current_url:
            self.navigate()
            
    def go_home(self):
        """导航到主页(默认为百度)"""
        self.url_entry.delete(0, tk.END)
        self.url_entry.insert(0, "https://www.baidu.com")
        self.navigate()
        
    def update_navigation_buttons(self):
        """更新导航按钮状态"""
        # 更新后退按钮状态
        if self.history_index > 0:
            self.back_button.config(state=tk.NORMAL)
        else:
            self.back_button.config(state=tk.DISABLED)
            
        # 更新前进按钮状态
        if self.history_index < len(self.history) - 1:
            self.forward_button.config(state=tk.NORMAL)
        else:
            self.forward_button.config(state=tk.DISABLED)

def main():
    """主函数"""
    # 创建主窗口
    root = tk.Tk()
    # 创建浏览器实例
    browser = Browser(root)
    # 默认打开百度首页
    browser.url_entry.insert(0, "https://www.baidu.com")
    browser.navigate()
    # 启动主事件循环
    root.mainloop()

if __name__ == "__main__":
    main()

功能说明

这个浏览器程序实现了以下功能:

  1. 导航功能:
    · 地址栏输入URL访问网页
    · 前进/后退按钮浏览历史记录
    · 刷新当前页面
    · 主页按钮返回默认首页
  2. 界面布局:
    · 顶部导航栏包含控制按钮和地址栏
    · 中部内容区域显示网页内容
    · 底部状态栏显示加载状态和信息
  3. 网页渲染:
    · 简化版HTML内容提取和显示
    · 提取页面标题和段落内容
    · 过滤脚本和样式标签
  4. 多线程加载:
    · 使用多线程加载网页,避免界面冻结
    · 加载过程中显示状态信息
  5. 错误处理:
    · 网络错误处理
    · URL格式验证和自动补全

使用说明

  1. 在地址栏输入URL(如:www.baidu.com)
  2. 按回车或点击"访问"按钮加载页面
  3. 使用前进/后退按钮浏览历史记录
  4. 点击刷新按钮重新加载当前页面
  5. 点击主页按钮返回百度首页

注意:这是一个简化版的浏览器,实际浏览器使用更复杂的渲染引擎(如WebKit/Blink/Gecko),这个程序仅用于演示基本概念。

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十一剑的CS_DN博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值