20252331 2025-2026-2 《Python程序设计》实验四报告

20252331 2025-2026-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2523
姓名: 肖鼎佶
学号:20252331
实验教师:王志强
实验日期:2026年6月14日
必修/选修: 公选课

1.实验内容

  • 选用中国天气网公开接口获取天气,合规可爬;
  • 实现功能:获取当日天气、和昨日气温对比、生成生活建议、采用「Server 酱」实现微信免费推送;
  • 逻辑:拉取天气 → 温湿度 / 气温对比 → 生成建议 → 推送微信

2. 实验过程及结果

1. 环境准备

代码依赖:requests;
屏幕截图 2026-06-14 172753

2. 具体设计

2.1 获取天气数据

点击查看代码
def get_weather():
    """获取天气数据"""
    try:
        res = requests.get(WEATHER_URL, timeout=10)
        res.raise_for_status()
        data = res.json()
        if data["status"] != 200:
            return None, "天气接口请求失败"
        return data, None
    except Exception as e:
        return None, f"网络异常:{str(e)}"
  • 用 requests.get() 向天气 API 发送请求,设置 timeout=10 防止程序卡死

  • res.raise_for_status() 自动判断 HTTP 请求是否成功(比如 404、500 错误)

  • 接口返回的是 JSON 格式,用 .json() 解析成 Python 字典

  • 判断接口状态码是否为 200(正常),如果不是则返回错误信息

  • 用 try-except 捕获所有网络异常(断网、超时、接口崩溃等),返回错误描述

2.2 判断气温变化

点击查看代码
def compare_temp(today_low, today_high, yesterday_low, yesterday_high):
    """今日与昨日气温对比"""
    diff_low = int(today_low) - int(yesterday_low)
    diff_high = int(today_high) - int(yesterday_high)
    tips = []

    if diff_low > 0:
        tips.append(f"最低温较昨日上升 {diff_low}℃")
    elif diff_low < 0:
        tips.append(f"最低温较昨日下降 {abs(diff_low)}℃")
    else:
        tips.append("最低温与昨日持平")

    if diff_high > 0:
        tips.append(f"最高温较昨日上升 {diff_high}℃")
    elif diff_high < 0:
        tips.append(f"最高温较昨日下降 {abs(diff_high)}℃")
    else:
        tips.append("最高温与昨日持平")

    return ",".join(tips)
  • 接收 4 个参数:今天的最高 / 最低温、昨天的最高 / 最低温
  • 计算温差:今天温度 - 昨天温度
  • 根据温差的正负判断 “上升 / 下降 / 持平”,拼接成自然语言
  • 用列表 tips 收集文案,最后用 join() 合并成一句话返回

2.3 推送简单生活建议

点击查看代码
ef get_life_suggest(weather_type, temp_high, wind):
    """根据天气生成生活建议"""
    suggest = []
    temp = int(temp_high)

    if temp >= 30:
        suggest.append("气温偏高,注意防暑降温,多补充水分")
    elif temp <= 10:
        suggest.append("气温偏低,注意增添衣物,做好保暖")
    elif 10 < temp < 30:
        suggest.append("气温舒适,适宜外出活动")

    rain_list = ["雨", "阵雨", "中雨", "大雨", "小雨"]
    if any(r in weather_type for r in rain_list):
        suggest.append("今日有雨,出门请携带雨具,注意路滑")
    elif "晴" in weather_type:
        suggest.append("天气晴朗,紫外线较强,外出建议做好防晒")
    elif "雾" in weather_type or "霾" in weather_type:
        suggest.append("能见度较差,减少户外长时间活动,佩戴口罩")

    if "3-4级" in wind or "4级" in wind:
        suggest.append("风力偏大,外出注意防风")

    return "\n".join(suggest)
  • 温度:根据最高温区间,给出防暑 / 保暖 / 舒适的建议
  • 天气状况:判断是否有雨 / 晴 / 雾霾,给出对应建议
  • 风力:判断是否为大风,给出防风建议
  • 所有建议收集在列表 suggest 中,最后用换行符拼接成段落,方便阅读

2.4 推送到微信

点击查看代码
def send_wechat(title, content):
    """通过Server酱推送消息到微信"""
    if not SEND_KEY:
        print("请先配置 Server酱 SendKey")
        return False
    push_url = f"https://sctapi.ftqq.com/{SEND_KEY}.send"
    params = {
        "title": title,
        "desp": content
    }
    try:
        res = requests.post(push_url, data=params, timeout=10)
        if res.json()["code"] == 0:
            print("微信推送成功!")
            return True
        else:
            print(f"推送失败:{res.json()['message']}")
            return False
    except Exception as e:
        print(f"推送异常:{str(e)}")
        return False
  • 先判断 SEND_KEY 是否配置,如果为空直接提示
  • 拼接 Server 酱的推送 API 地址
  • 用 requests.post() 发送 POST 请求,带上标题和内容
  • 判断接口返回的 code 是否为 0(Server 酱约定 0 为成功)
  • 捕获网络异常,返回推送结果(成功 / 失败)

2.5 配置区

点击查看代码
# 1. Server酱 SendKey
SEND_KEY = "SCT364288T4Y6J2kanYRBHnkJmHT4wY8J4"
# 2. 城市代码:北京市丰台区 101010900
CITY_CODE = "101010900"
# 3. 天气接口地址
WEATHER_URL = f"http://t.weather.itboy.net/api/weather/city/{CITY_CODE}"

  • SEND_KEY:微信推送服务的身份密钥,用于验证推送权限。
  • CITY_CODE:目标城市编码,当前配置为北京市丰台区,更换城市只需修改该值。
  • WEATHER_URL:天气接口地址,根据城市编码动态拼接,自动适配对应地区数据。

2.6 清洗温度字符串,只提取纯数字

点击查看代码
def extract_number(s):
    """清洗温度字符串,只提取纯数字"""
    num_str = ""
    for char in s:
        if char.isdigit():
            num_str += char
    return num_str

2.7 整体代码实现

点击查看代码
import requests


SEND_KEY = "SCT364288T4Y6J2kanYRBHnkJmHT4wY8J4"
# 北京市丰台区
CITY_CODE = "101010900"
WEATHER_URL = f"http://t.weather.itboy.net/api/weather/city/{CITY_CODE}"

def get_weather():
    """获取天气数据"""
    try:
        res = requests.get(WEATHER_URL, timeout=10)
        res.raise_for_status()
        data = res.json()
        if data["status"] != 200:
            return None, "天气接口请求失败"
        return data, None
    except Exception as e:
        return None, f"网络异常:{str(e)}"

def extract_number(s):
    """清洗温度字符串,只提取纯数字"""
    num_str = ""
    for char in s:
        if char.isdigit():
            num_str += char
    return num_str

def compare_temp(today_low, today_high, yesterday_low, yesterday_high):
    """今日与昨日气温对比"""
    diff_low = int(today_low) - int(yesterday_low)
    diff_high = int(today_high) - int(yesterday_high)
    tips = []

    if diff_low > 0:
        tips.append(f"最低温较昨日上升 {diff_low}℃")
    elif diff_low < 0:
        tips.append(f"最低温较昨日下降 {abs(diff_low)}℃")
    else:
        tips.append("最低温与昨日持平")

    if diff_high > 0:
        tips.append(f"最高温较昨日上升 {diff_high}℃")
    elif diff_high < 0:
        tips.append(f"最高温较昨日下降 {abs(diff_high)}℃")
    else:
        tips.append("最高温与昨日持平")

    return ",".join(tips)

def get_life_suggest(weather_type, temp_high, wind):
    """根据天气生成生活建议"""
    suggest = []
    temp = int(temp_high)

    if temp >= 30:
        suggest.append("气温偏高,注意防暑降温,多补充水分")
    elif temp <= 10:
        suggest.append("气温偏低,注意增添衣物,做好保暖")
    elif 10 < temp < 30:
        suggest.append("气温舒适,适宜外出活动")

    rain_list = ["雨", "阵雨", "中雨", "大雨", "小雨"]
    if any(r in weather_type for r in rain_list):
        suggest.append("今日有雨,出门请携带雨具,注意路滑")
    elif "晴" in weather_type:
        suggest.append("天气晴朗,紫外线较强,外出建议做好防晒")
    elif "雾" in weather_type or "霾" in weather_type:
        suggest.append("能见度较差,减少户外长时间活动,佩戴口罩")

    if "3-4级" in wind or "4级" in wind:
        suggest.append("风力偏大,外出注意防风")

    return "\n".join(suggest)

def send_wechat(title, content):
    """通过Server酱推送消息到微信"""
    if not SEND_KEY:
        print("请先配置 Server酱 SendKey")
        return False
    push_url = f"https://sctapi.ftqq.com/{SEND_KEY}.send"
    params = {
        "title": title,
        "desp": content
    }
    try:
        res = requests.post(push_url, data=params, timeout=10)
        if res.json()["code"] == 0:
            print("微信推送成功!")
            return True
        else:
            print(f"推送失败:{res.json()['message']}")
            return False
    except Exception as e:
        print(f"推送异常:{str(e)}")
        return False

def main():
    weather_data, err = get_weather()
    if err:
        print(err)
        return

    city = weather_data["cityInfo"]["city"]
    today = weather_data["data"]["forecast"][0]
    yesterday = weather_data["data"]["forecast"][1]

    today_weather = today["type"]
    # 统一调用清洗函数
    today_low = extract_number(today["low"])
    today_high = extract_number(today["high"])
    today_wind = today["fx"] + today["fl"]
    today_date = today["ymd"] + " " + today["week"]

    yesterday_low = extract_number(yesterday["low"])
    yesterday_high = extract_number(yesterday["high"])

    compare_info = compare_temp(today_low, today_high, yesterday_low, yesterday_high)
    life_tips = get_life_suggest(today_weather, today_high, today_wind)

    title = f"【{city}】每日天气提醒"
    content = f"""
📅 日期:{today_date}
🌤 天气:{today_weather}
🌡 温度:{today_low} ~ {today_high}℃
💨 风向风力:{today_wind}

📊 气温对比:
{compare_info}

💡 生活建议:
{life_tips}
"""
    print(content)
    send_wechat(title, content)

if __name__ == "__main__":
    main()

3. 运行结果

屏幕截图 2026-06-14 192022

69c14a3993ff38cacb1480ef1d535861

4. 遇到的问题

  • 问题:本来想通过爬取抖音实现视频自动下载,但是由于抖音反爬虫功能强大,无法爬取
  • 解决方法:查询可以简单爬取的网站,例如中国天气网,实现自动化推送天气信息和简单建议

3. 课程内容总结与感想体会

3.1 内容总结:

  • 字符串操作:
    strip ()、find ()、count () 字符串内置方法;文本截取、内容查找、字符统计;
  • 序列的应用
    Python 常见序列分为列表、元组、字典、集合四大类,各自特性不同:列表可变、支持丰富增删改操作;元组不可变、访问效率高;字典以键值对存储,通过键取值;集合元素唯一,可做交并集运算。序列通用操作包含索引、切片、遍历,同时每种序列都有专属方法,是 Python 基础数据结构。
    字符串与正则表达式
    字符串提供查找、分割、去空格、大小写转换、格式化等常用方法,可高效处理普通文本。正则表达式是专业文本匹配规则,搭配re模块,借助元字符、限定符,实现复杂查找、替换、分割,能解决普通字符串难以处理的模糊匹配场景。
  • 函数
    函数用于封装重复代码,提升复用性与可读性。支持位置参数、默认参数、可变参数,可设置返回值;还提供lambda匿名函数,用于编写简短逻辑。函数划分代码模块,是程序结构化编程的基础。
    面向对象程序设计
    核心概念为类和对象,拥有封装、继承、多态三大核心特性。__init__是构造方法,创建对象时自动执行;通过单、双下划线控制属性和方法的访问权限,适合开发大型、易维护的程序。
  • 模块与异常处理
    模块就是独立的.py文件,可导入使用外部代码,实现功能拆分。程序运行报错会触发异常,通过try-except语句捕获、处理异常,避免程序直接崩溃,也可结合raise主动抛出异常。
    文件及目录操作
    使用open()函数打开文件,实现文本、二进制内容的读取与写入;os模块专门管理文件夹,支持查看路径、创建 / 删除目录、遍历文件等操作,可实现本地文件自动化管理。
  • 数据库
    数据库用于长期存储结构化数据。介绍了轻量级嵌入式数据库 SQLite 和主流关系型数据库 MySQL,Python 可通过对应驱动连接数据库,使用 SQL 语句完成数据增、删、改、查全套操作。
  • Socket 编程技术
    Socket(套接字)由IP + 端口组成,是网络通信的接口。主要分为 TCP 面向连接、UDP 面向无连接两种通信方式;编程分为服务端(绑定端口、监听连接)和客户端(主动连接),双方建立通道后即可收发数据。
  • 网络爬虫技术
    网络爬虫模拟浏览器访问网页,核心流程为发送网络请求、解析页面数据。常用urllib、requests库发请求,lxml、BeautifulSoup 解析网页;网站常通过 403、验证码做反爬,可借助请求头、超时、代理 IP 规避,也可使用 Scrapy 等专业爬虫框架。

3.2 感想体会

通过这段时间 Python 基础到网络编程的学习,我收获很大。课程让我逐步搭建起完整的 Python 知识体系。理论容易理解,但是内容相当多,要清楚记住难度很大,动手实操总会遇到报错、逻辑漏洞,这让我明白编程重在练习,熟能生巧。后续我会继续多敲代码、积累经验,把所学知识灵活运用到实际场景中。python应用场景十分广泛,不同于C语言,python能够直接的实现丰富的功能,依托成熟的第三方库,快速开发、实现各类功能。同时课程也教导我们要保持终身学习,持之以恒地提升自己的能力。

posted @ 2026-06-14 19:27  肖大林  阅读(10)  评论(0)    收藏  举报