Skip to content

第三章 Python基础 ​

数据分析与挖掘系列教程


目录 ​

  1. 数据结构与方法
  2. 流程控制语句
  3. 字符串处理
  4. 函数定义与使用
  5. 实战案例:网页爬虫

1. 数据结构与方法 ​

1.1 变量赋值 ​

两种赋值方式 ​

python
# 方式1:直接赋值
name = "张三"
age = 25

# 方式2:交互式输入
user_input = input("请输入内容:")
# 注意:input()返回的永远是字符串类型

⚠️ 重要提示:input() 函数返回的值始终是字符串,需要类型转换才能用于数值计算。

python
age = int(input("请输入年龄:"))  # 转换为整数
price = float(input("请输入价格:"))  # 转换为浮点数

1.2 列表(List) ​

特性概览 ​

  • 构造符号:方括号 []
  • 元素类型:无限制(数值、字符串、列表等)
  • 有序性:支持索引和切片
  • 可变性:可修改、增删元素

基础示例 ​

python
# 创建列表
students = ['张三', '李四', '王五']
mixed_list = [1, 3.14, True, 'Python', [1, 2, 3]]

索引技术 ​

索引类型语法示例说明
正向单索引list[n]students[0] → '张三'从0开始计数
负向单索引list[-n]students[-1] → '王五'从-1开始倒数
切片list[start:end:step]students[0:2] → ['张三', '李四']不包含end位置
无限切片list[:n] 或 list[n:]students[:2] → 前2个元素省略起点或终点
python
data = ['A', 'B', 'C', 'D', 'E', 'F']

# 正向索引
print(data[0])      # 'A' - 第1个元素
print(data[2])      # 'C' - 第3个元素

# 负向索引
print(data[-1])     # 'F' - 最后1个元素
print(data[-2])     # 'E' - 倒数第2个元素

# 切片操作
print(data[1:4])    # ['B', 'C', 'D'] - 索引1到3
print(data[::2])    # ['A', 'C', 'E'] - 每隔1个取值
print(data[::-1])   # ['F', 'E', 'D', 'C', 'B', 'A'] - 反转列表

列表方法 ​

增加元素

python
fruits = ['苹果', '香蕉']

# append: 添加单个元素到末尾
fruits.append('橙子')  # ['苹果', '香蕉', '橙子']

# extend: 批量添加多个元素
fruits.extend(['葡萄', '西瓜'])  # ['苹果', '香蕉', '橙子', '葡萄', '西瓜']

# insert: 在指定位置插入
fruits.insert(1, '草莓')  # ['苹果', '草莓', '香蕉', '橙子', '葡萄', '西瓜']

删除元素

python
numbers = [1, 2, 3, 4, 5, 3]

# pop: 根据索引删除(默认删除最后一个)
numbers.pop()      # 删除5,返回5
numbers.pop(0)     # 删除1,返回1

# remove: 根据值删除(仅删除第一个匹配项)
numbers.remove(3)  # 删除第一个3

# clear: 清空列表
numbers.clear()    # []

修改元素

python
colors = ['红', '绿', '蓝']
colors[1] = '黄'  # ['红', '黄', '蓝']

其他常用方法

python
nums = [3, 1, 4, 1, 5, 9, 2, 6]

# 统计元素出现次数
print(nums.count(1))  # 2

# 查找元素索引
print(nums.index(5))  # 4

# 排序(会修改原列表)
nums.sort()           # 升序排序
nums.sort(reverse=True)  # 降序排序

# 反转列表
nums.reverse()

# 复制列表
nums_copy = nums.copy()

1.3 元组(Tuple) ​

特性概览 ​

  • 构造符号:圆括号 ()
  • 不可变性:创建后无法修改
  • 性能优势:比列表更快,占用内存更少
  • 适用场景:存储不应被修改的数据
python
# 创建元组
coordinates = (10, 20)
person = ('张三', 25, '北京')

# 单元素元组需要加逗号
single = (42,)  # 正确
not_tuple = (42)  # 这是整数,不是元组

# 元组支持索引和切片(与列表相同)
print(person[0])     # '张三'
print(person[-1])    # '北京'

# 仅有的两个方法
print(person.count('张三'))  # 1
print(person.index(25))      # 1

⚠️ 元组的不可变性:元组本身不可变,但如果元组包含可变对象(如列表),该对象的内容可以改变。

python
data = (1, 2, [3, 4])
# data[0] = 10  # 报错!元组不可修改
data[2].append(5)  # 可以!修改列表内容
print(data)  # (1, 2, [3, 4, 5])

1.4 字典(Dictionary) ​

特性概览 ​

  • 构造符号:大括号 {}
  • 存储方式:键值对(key: value)
  • 键的要求:唯一且不可变(字符串、数字、元组)
  • 无序性:Python 3.7+ 保持插入顺序
python
# 创建字典
student = {
    "姓名": "张三",
    "年龄": 20,
    "专业": "计算机科学",
    "成绩": [85, 90, 88]
}

# 嵌套字典
company = {
    "名称": "科技公司",
    "员工": {
        "技术部": ["张三", "李四"],
        "市场部": ["王五", "赵六"]
    }
}

字典操作 ​

获取值

python
# 方式1:键索引(键不存在会报错)
print(student["姓名"])  # '张三'

# 方式2:get方法(键不存在返回None或默认值)
print(student.get("姓名"))      # '张三'
print(student.get("电话"))      # None
print(student.get("电话", "未设置"))  # '未设置'

增加/修改

python
scores = {"数学": 90, "英语": 85}

# 直接赋值
scores["物理"] = 88       # 新增
scores["数学"] = 95       # 修改

# setdefault:仅当键不存在时添加
scores.setdefault("化学", 80)  # 新增
scores.setdefault("数学", 100)  # 不修改已有值

# update:批量更新
scores.update({"语文": 92, "数学": 96})

删除

python
info = {"name": "Tom", "age": 25, "city": "Beijing"}

# pop:删除指定键
age = info.pop("age")  # 返回25

# popitem:删除最后插入的键值对(3.7+)
item = info.popitem()  # 返回 ('city', 'Beijing')

# del:删除指定键
del info["name"]

# clear:清空字典
info.clear()

常用方法

python
book = {
    "title": "Python编程",
    "author": "张三",
    "year": 2024
}

# 获取所有键
print(book.keys())    # dict_keys(['title', 'author', 'year'])

# 获取所有值
print(book.values())  # dict_values(['Python编程', '张三', 2024])

# 获取所有键值对
print(book.items())   # dict_items([('title', 'Python编程'), ...])

# 遍历字典
for key, value in book.items():
    print(f"{key}: {value}")

1.5 方法 vs 函数 ​

特性方法(Method)函数(Function)
归属属于特定对象/类独立存在
调用对象.方法()函数(参数)
示例list.append()len(), print()
python
# 方法调用
my_list = [1, 2, 3]
my_list.append(4)  # append是列表的方法

# 函数调用
length = len(my_list)  # len是内置函数
print(length)          # print是内置函数

卫哥の上课笔记 / 内部资料

2. 流程控制语句 ​

2.1 条件语句(if-elif-else) ​

基本语法 ​

python
if 条件1:
    代码块1
elif 条件2:
    代码块2
else:
    代码块3

⚠️ 语法要点:

  • 每个条件后必须有冒号 :
  • 代码块必须缩进(通常4个空格)
  • elif 不是 elseif
  • else 后面不写条件

实例:成绩等级判定 ​

python
score = int(input("请输入成绩:"))

if score >= 90:
    grade = "优秀"
elif score >= 80:
    grade = "良好"
elif score >= 60:
    grade = "及格"
else:
    grade = "不及格"

print(f"成绩等级:{grade}")

条件表达式(三元运算符) ​

python
# 传统写法
if x > 0:
    result = "正数"
else:
    result = "非正数"

# 简洁写法
result = "正数" if x > 0 else "非正数"

2.2 for循环 ​

基本语法 ​

python
for 变量 in 可迭代对象:
    代码块

常见用法 ​

python
# 遍历列表
fruits = ['苹果', '香蕉', '橙子']
for fruit in fruits:
    print(fruit)

# 遍历字符串
for char in "Python":
    print(char)

# 使用range生成数字序列
for i in range(5):      # 0, 1, 2, 3, 4
    print(i)

for i in range(1, 6):   # 1, 2, 3, 4, 5
    print(i)

for i in range(0, 10, 2):  # 0, 2, 4, 6, 8
    print(i)

# 遍历字典
person = {"name": "Tom", "age": 25}
for key in person:
    print(key, person[key])

for key, value in person.items():
    print(f"{key}: {value}")

实例:计算1-100偶数和 ​

python
total = 0
for num in range(1, 101):
    if num % 2 == 0:
        total += num
print(f"1-100偶数和:{total}")  # 2550

enumerate:同时获取索引和值 ​

python
colors = ['红', '绿', '蓝']
for index, color in enumerate(colors):
    print(f"索引{index}: {color}")

卫哥の上课笔记 / 内部资料

2.3 列表推导式 ​

基本语法 ​

python
[表达式 for 变量 in 可迭代对象 if 条件]

对比传统循环 ​

python
# 传统for循环
squares = []
for x in range(10):
    squares.append(x ** 2)

# 列表推导式(更简洁)
squares = [x ** 2 for x in range(10)]

高级用法 ​

python
# 带条件筛选
even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]

# 嵌套推导式
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

# 字符串处理
words = ['hello', 'WORLD', 'Python']
upper_words = [w.upper() for w in words]
# ['HELLO', 'WORLD', 'PYTHON']

2.4 while循环 ​

基本语法 ​

python
while 条件:
    代码块

for vs while ​

特性for循环while循环
适用场景已知迭代次数/对象未知迭代次数
示例遍历列表用户登录验证

实例:登录验证 ​

python
max_attempts = 3
attempts = 0

while attempts < max_attempts:
    username = input("用户名:")
    password = input("密码:")
    
    if username == "admin" and password == "123456":
        print("登录成功!")
        break
    else:
        attempts += 1
        remaining = max_attempts - attempts
        if remaining > 0:
            print(f"登录失败,还有{remaining}次机会")
        else:
            print("账户已锁定,请联系管理员")

无限循环与break ​

python
# 无限循环(需要break退出)
while True:
    command = input("输入命令(输入'退出'结束):")
    if command == "退出":
        break
    print(f"执行命令:{command}")

3. 字符串处理 ​

3.1 字符串基础 ​

创建方式 ​

python
# 单引号
s1 = 'Hello'

# 双引号
s2 = "World"

# 三引号(支持多行)
s3 = '''这是
多行
字符串'''

# 原始字符串(忽略转义符)
path = r"C:\Users\name\Documents"

字符串是不可变的 ​

python
text = "Python"
# text[0] = 'J'  # 报错!字符串不可修改

# 正确做法:创建新字符串
text = "J" + text[1:]  # "Jython"

3.2 字符串方法 ​

切片操作 ​

python
text = "Python Programming"

print(text[0:6])    # "Python"
print(text[7:])     # "Programming"
print(text[:6])     # "Python"
print(text[::2])    # "Pto rgamn"
print(text[::-1])   # "gnimmargorP nohtyP" (反转)

常用方法速查 ​

方法功能示例
split(sep)分割字符串"a-b-c".split("-") → ['a', 'b', 'c']
join(iterable)连接字符串"-".join(['a', 'b']) → "a-b"
strip()去除首尾空白" hello ".strip() → "hello"
replace(old, new)替换子串"hello".replace("l", "L") → "heLLo"
upper() / lower()大小写转换"Hello".upper() → "HELLO"
startswith(prefix)检查开头"Python".startswith("Py") → True
endswith(suffix)检查结尾"test.py".endswith(".py") → True
find(sub)查找子串"hello".find("ll") → 2
count(sub)计数子串"banana".count("a") → 3

实用示例 ​

python
# 提取身份证号中的出生日期
print("123456198901017890"[6:14])  # 输出:19890101

# 将手机号中间四位替换为*
tel = "13612345678"
print(tel.replace(tel[3:7], "****"))  # 输出:136****5678

# 分割字符串
print("12345@qq.com".split("@"))  # 输出:["12345", "qq.com"]

# 用逗号连接字符串
print(",".join("Python"))  # 输出:P,y,t,h,o,n

# 去除空白
print("  今天星期日  ".lstrip())  # 去除左空白
print("  今天星期日  ".rstrip())  # 去除右空白
print("  今天星期日  ".strip())   # 去除首尾空白

# 子串计数
string5 = "中国方案引领世界前行,展现了中国应势而为、勇于担当的大国风范!"
print(string5.count("中国"))  # 输出:2

# 查找子串位置
string6 = "我是一名Python用户,Python给我的工作带来了很多便捷。"
print(string6.index("Python"))  # 输出:6
print(string6.find("Python"))   # 输出:6

# 判断字符串开头和结尾
string7 = "2017年已过,但全新的2018年即将到来"
print(string7.startswith("2018年"))  # 输出:False
print(string7.endswith("2018年"))    # 输出:False

卫哥の上课笔记 / 内部资料

3.3 正则表达式 ​

导入re模块 ​

python
import re

核心函数 ​

函数功能语法
findall()查找所有匹配项re.findall(pattern, string)
search()查找第一个匹配项re.search(pattern, string)
sub()替换匹配项re.sub(pattern, repl, string)
split()按模式分割re.split(pattern, string)

常用正则符号 ​

符号含义示例
.任意字符(除换行符)a.c 匹配 "abc", "a1c"
\d数字 [0-9]\d{3} 匹配 "123"
\D非数字\D+ 匹配 "abc"
\w字母、数字、下划线\w+ 匹配 "hello_123"
\s空白字符\s+ 匹配空格、制表符
*0次或多次ab* 匹配 "a", "ab", "abb"
+1次或多次ab+ 匹配 "ab", "abb"
?0次或1次ab? 匹配 "a", "ab"
{m,n}m到n次a{2,4} 匹配 "aa", "aaa", "aaaa"
[]字符集[abc] 匹配 "a", "b", "c"
[^]非字符集[^0-9] 匹配非数字
|或cat|dog 匹配 "cat" 或 "dog"
()分组/捕获(ab)+ 匹配 "ab", "abab"

实战案例 ​

提取邮箱地址

python
text = "联系我:admin@example.com 或 support@test.org"
emails = re.findall(r'\w+@\w+\.\w+', text)
print(emails)  # ['admin@example.com', 'support@test.org']

提取手机号

python
text = "我的手机号是13812345678,备用号码是15987654321"
phones = re.findall(r'1[3-9]\d{9}', text)
print(phones)  # ['13812345678', '15987654321']

清理HTML标签

python
html = "<p>这是<b>加粗</b>文本</p>"
clean_text = re.sub(r'<[^>]+>', '', html)
print(clean_text)  # "这是加粗文本"

提取日期

python
text = "会议时间:2024-03-15 和 2024/04/20"
dates = re.findall(r'\d{4}[-/]\d{2}[-/]\d{2}', text)
print(dates)  # ['2024-03-15', '2024/04/20']

分组捕获

python
text = "价格:¥199.99元"
match = re.search(r'¥(\d+\.\d{2})', text)
if match:
    price = match.group(1)  # "199.99"
    print(f"提取的价格:{price}")

卫哥の上课笔记 / 内部资料

4. 函数定义与使用 ​

4.1 匿名函数(Lambda) ​

语法格式 ​

python
lambda 参数: 表达式

特点 ​

  • 单行表达式
  • 无需def关键字
  • 常用于临时性、简单的函数

基础示例 ​

python
# 普通函数
def add(x, y):
    return x + y

# 等价的Lambda函数
add_lambda = lambda x, y: x + y

print(add(3, 5))         # 8
print(add_lambda(3, 5))  # 8

实用场景 ​

排序

python
# 按字符串长度排序
words = ['python', 'java', 'c', 'javascript']
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words)  # ['c', 'java', 'python', 'javascript']

# 按字典值排序
scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78}
sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
print(sorted_scores)  # [('Bob', 92), ('Alice', 85), ('Charlie', 78)]

数据处理

python
# map:对每个元素应用函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# filter:筛选元素
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # [2, 4]

4.2 自定义函数(def) ​

基本语法 ​

python
def 函数名(参数列表):
    """文档字符串(可选)"""
    函数体
    return 返回值  # 可选

参数类型 ​

必需参数

python
def greet(name):
    return f"你好,{name}!"

print(greet("张三"))  # "你好,张三!"
# greet()  # 报错:缺少必需参数

默认参数

python
def power(base, exponent=2):
    return base ** exponent

print(power(3))      # 9 (3^2)
print(power(3, 3))   # 27 (3^3)

关键字参数

python
def create_profile(name, age, city="未知"):
    return f"{name}, {age}岁, 来自{city}"

# 位置传参
print(create_profile("张三", 25, "北京"))

# 关键字传参(顺序可变)
print(create_profile(age=25, name="张三", city="上海"))

可变参数

python
# *args:接收任意数量位置参数(元组)
def sum_all(*numbers):
    return sum(numbers)

print(sum_all(1, 2, 3, 4))  # 10

# **kwargs:接收任意数量关键字参数(字典)
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Tom", age=25, city="Beijing")

返回值 ​

python
# 单个返回值
def square(x):
    return x ** 2

# 多个返回值(返回元组)
def divide(a, b):
    quotient = a // b
    remainder = a % b
    return quotient, remainder

q, r = divide(10, 3)
print(q, r)  # 3 1

# 无返回值(返回None)
def print_message(msg):
    print(msg)

文档字符串 ​

python
def calculate_bmi(weight, height):
    """
    计算BMI指数
    
    参数:
        weight (float): 体重(千克)
        height (float): 身高(米)
    
    返回:
        float: BMI值
    """
    return weight / (height ** 2)

# 查看文档
help(calculate_bmi)
print(calculate_bmi.__doc__)

4.3 实用函数示例 ​

示例1:温度转换 ​

python
def celsius_to_fahrenheit(celsius):
    """摄氏度转华氏度"""
    return celsius * 9/5 + 32

def fahrenheit_to_celsius(fahrenheit):
    """华氏度转摄氏度"""
    return (fahrenheit - 32) * 5/9

print(f"25°C = {celsius_to_fahrenheit(25)}°F")
print(f"77°F = {fahrenheit_to_celsius(77):.1f}°C")

示例2:列表去重保序 ​

python
def unique_list(items):
    """去除列表重复元素,保持顺序"""
    seen = set()
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

numbers = [1, 3, 2, 3, 4, 1, 5]
print(unique_list(numbers))  # [1, 3, 2, 4, 5]

示例3:递归函数 ​

python
def factorial(n):
    """计算阶乘(递归)"""
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 120

def fibonacci(n):
    """斐波那契数列(递归)"""
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print([fibonacci(i) for i in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

卫哥の上课笔记 / 内部资料

5. 实战案例:网页爬虫 ​

5.1 案例:爬取天气数据 ​

技术栈 ​

  • requests:发送HTTP请求
  • re:正则表达式提取数据
  • pandas:数据处理与存储
  • time & random:请求延迟(防反爬)

完整代码 ​

python
import requests
import time
import random
import pandas as pd
import re

# 1. 配置请求头(模拟浏览器)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept': '*/*',
    'Connection': 'keep-alive'
}

# 2. 生成目标URL列表
urls = []
for year in range(2020, 2024):
    for month in range(1, 13):
        url = f'http://tianqi.2345.com/t/wea_history/5/{year}/{month:02d}/58362.htm'
        urls.append(url)

# 3. 爬取数据
all_data = []

for idx, url in enumerate(urls, 1):
    try:
        # 随机延迟3-6秒(避免被封)
        time.sleep(random.uniform(3, 6))
        
        # 发送请求
        response = requests.get(url, headers=headers, timeout=10)
        response.encoding = 'utf-8'
        
        # 正则提取数据
        dates = re.findall(r'"ymd":"(.*?)"', response.text)
        high_temp = re.findall(r'"bendu":"(.*?)℃"', response.text)
        low_temp = re.findall(r'"wendu":"(.*?)℃"', response.text)
        weather = re.findall(r'"tianqi":"(.*?)"', response.text)
        
        # 组织数据
        df = pd.DataFrame({
            '日期': dates,
            '最高温': high_temp,
            '最低温': low_temp,
            '天气': weather
        })
        all_data.append(df)
        
        print(f"已完成 {idx}/{len(urls)}")
        
    except Exception as e:
        print(f"URL {url} 爬取失败:{e}")

# 4. 合并并保存数据
if all_data:
    final_data = pd.concat(all_data, ignore_index=True)
    final_data.to_csv('weather_data.csv', index=False, encoding='utf-8-sig')
    print(f"\n爬取完成!共 {len(final_data)} 条数据")

5.2 爬虫关键技术 ​

反爬策略应对 ​

反爬手段应对方法
User-Agent检测设置headers模拟浏览器
访问频率限制随机延迟(time.sleep)
IP封禁使用代理IP池
JavaScript渲染使用Selenium/Playwright

请求头设置 ​

python
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
    'Referer': 'https://www.example.com',  # 来源页面
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'session_id=xxx'  # 登录态
}

异常处理 ​

python
try:
    response = requests.get(url, timeout=10)
    response.raise_for_status()  # 检查HTTP错误
except requests.Timeout:
    print("请求超时")
except requests.HTTPError as e:
    print(f"HTTP错误:{e}")
except Exception as e:
    print(f"未知错误:{e}")

5.3 数据清洗示例 ​

python
import pandas as pd

# 读取爬取的数据
df = pd.read_csv('weather_data.csv')

# 数据清洗
df['日期'] = pd.to_datetime(df['日期'])  # 转换日期格式
df['最高温'] = df['最高温'].str.replace('℃', '').astype(int)
df['最低温'] = df['最低温'].str.replace('℃', '').astype(int)

# 数据分析
print(df.describe())  # 统计描述
print(df['天气'].value_counts())  # 天气分布

# 可视化(需要matplotlib)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文显示

df.plot(x='日期', y=['最高温', '最低温'], figsize=(12, 6))
plt.title('气温变化趋势')
plt.xlabel('日期')
plt.ylabel('温度(℃)')
plt.show()

附录:学习资源 ​

官方文档 ​

推荐练习平台 ​

进阶学习路径 ​

  1. 基础巩固:数据结构 → 流程控制 → 函数
  2. 数据处理:Pandas → NumPy → 数据可视化
  3. 爬虫进阶:Selenium → Scrapy框架
  4. 数据分析:统计分析 → 机器学习 → 深度学习

快速参考 ​

Python内置函数 ​

python
# 类型转换
int(), float(), str(), list(), dict(), tuple()

# 数学运算
abs(), round(), max(), min(), sum(), pow()

# 序列操作
len(), sorted(), reversed(), enumerate(), zip()

# 输入输出
print(), input()

# 其他
type(), isinstance(), help(), dir()

常用快捷操作 ​

python
# 交换变量
a, b = b, a

# 多重赋值
x = y = z = 0

# 链式比较
1 < x < 10

# 条件表达式
result = "偶数" if num % 2 == 0 else "奇数"

# 列表去重
unique = list(set(my_list))

# 字典合并(Python 3.9+)
merged = dict1 | dict2

编写日期:2024年
适用版本:Python 3.6+
文档状态:持续更新

© 2026 卫の课程教学资料
仅限学员学习使用,禁止任何形式传播
📢 版权声明:本文首发于 [https://zhangwei.gitbook.io/],禁止非法爬取或转载。 验证指纹 ID:GB-2026-0116

基于 Vite 强力驱动 | 纯静态轻量托管