资讯动态

用Python定时抓取天气并推送到企业微信机器人

发布时间:2026/10/15 12:46:58 来源:尧图企业网站定制
简介面向需要自动向微信好友推送指定城市天气的Python学习者这份压缩包提供了一套完整的定时任务脚本方案覆盖天气数据抓取、城市代码匹配、定时调度与微信消息发送等环节适合有一定Python基础、希望实践爬虫和自动化通知的开发者参考。压缩包共7个文件由6个py脚本与1个城市代码文本文件构成整体仅7KB代码量精简且模块划分清晰便于快速阅读和二次修改。已有1450人学习下载说明该案例对相似需求具有较高的参考价值。通过阅读代码可以掌握使用requests请求天气接口并解析返回信息的思路理解Timer定时器如何驱动周期任务以及如何将微信好友发送逻辑独立封装同时城市代码文本文件展示了城市与代码的映射方式为实现多城市天气监控、定时关怀提醒等功能提供了可直接复用的脚本模块与工程组织方法。1. 每天定时发一条天气给关心的人这事值不值你在外地工作手机里存着老家和几个重要朋友的微信每天想问候又不知道说什么。天气就是那个最自然的开场白。与其早上醒来翻天气再复制粘贴不如写一个 Python 定时任务每天七点把指定城市的天气抓下来算好穿衣建议直接推到群里的微信好友。这个脚本的全部价值就一句话把“想关心但没空表达”变成“每天自动送到”。适合有一定 Python 基础、想落地一个真实小工具的开发者也适合第一次接触定时任务和 webhook 推送的人。整个项目只依赖 requests 和 APScheduler 两个库不碰手机协议不用复杂框架。2. 天气数据从哪来选对数据源后面少踩一半坑2.1 为什么先从公共天气接口入手而不是直接上商业 API很多第一次做天气脚本的人第一反应是注册一个商业天气平台的账号拿 API Key。这确实省事但有几个现实问题免费额度有限个人开发用着用着就超限部分平台要求实名甚至绑卡还有不少平台把“实时天气”和“生活指数”拆成不同接口每个都要单独调。更麻烦的是一旦你把 key 写死在脚本里半年后 key 过期定时任务就悄悄断掉了。我一般会先看目标城市所在的公共天气服务网页。这类网页本身是给人看的每天更新城市代码稳定不限制个人访问频率。只要解析其中的结构化区块就能拿到温度、湿度、风力和天气现象。缺点是有反爬风险但我们的频率是每天一次远低于正常访问量风险很小。另一个常见做法是直接调用高德或和风天气的公开 JSON 接口只要不需要实时分钟级数据免费档就够用。选择数据源时有一个判断标准你的脚本多久跑一次。每天一次属于低频不需要商业 SLA反而更需要“代码不发散、字段稳定、不登录也能拿”。公共天气网页恰好满足这三点。如果将来数据源改版你只需要改一个解析函数不影响推送链路。2.2 城市代码先看懂 URL 里的编码规律再写抓取几乎所有天气网页都有一个特点每个城市对应一串数字编码编码出现在 URL 里。比如某个页面结构是/city/101010100.html最后的九位数字就是城市代码。这个代码不是随机生成的通常遵循“省级-市级-区县”的分段规则。我们没必要去研究编码算法只要能把“城市名”映射到“城市代码”就行。我的做法是把城市代码放在一个独立的city.json文件里结构是{城市名: 101010100}。这样改动一个城市不需要改脚本只需要修改配置。脚本启动时读取这个文件通过命令行参数选择目标城市。放在配置文件里的原因很简单定时任务里的命令越短越好如果哪天要换个城市推送不去动 Python 代码只改 json 文件风险最小。获取城市代码的路径一般是先打开对应的天气网页手动查一次目标城市看浏览器地址栏最后的数字串或者爬取网站的省份城市列表页但那是另一个复杂度。对个人脚本来说手动查一次花两分钟比写一个城市列表抓虫器值得。2.3 用 requests 加 BeautifulSoup 抓取页面核心字段确定了页面结构后抓取逻辑就很清晰。下面是核心代码它抓取页面上几个关键区块当前温度、天气现象、湿度和风向。为了让代码能直接跑我用了BASE_URL和CITY_CODE作为占位你使用时替换成实际服务的地址和城市代码。import requests from bs4 import BeautifulSoup BASE_URL https://weather.example.com/{city_code}.html # 替换为实际天气页面 CITY_CODE 101010100 # 替换为目标城市代码 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Referer: BASE_URL.format(city_codeCITY_CODE) } def fetch_weather(city_code: str) - dict: url BASE_URL.format(city_codecity_code) resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() resp.encoding utf-8 soup BeautifulSoup(resp.text, html.parser) # 提取当前温度页面里通常有一个 class 包含 now 和 temp temp_tag soup.select_one(.now .temp) weather_tag soup.select_one(.now .weather) humidity_tag soup.select_one(.now .humidity) wind_tag soup.select_one(.now .wind) data { temp: temp_tag.text.strip() if temp_tag else N/A, weather: weather_tag.text.strip() if weather_tag else N/A, humidity: humidity_tag.text.strip() if humidity_tag else N/A, wind: wind_tag.text.strip() if wind_tag else N/A, } return data if __name__ __main__: print(fetch_weather(CITY_CODE))这段代码的关键点有两个。第一headers里必须带User-Agent和Referer缺少任何一个某些站点会直接返回 403 或跳转到验证页。第二timeout10是必须的天气接口偶尔会慢如果没有超时控制定时任务会卡在请求上后面推送全部排队。2.4 字段解析温度、天气、风向、湿度一起拿上面的代码只拿“当前”数据但给好友看的消息最好还包含最低温和最高温。很多天气页面在另一个区块里放着一天的预报比如“白天最高温 18 度夜间最低温 9 度”。如果只抓当前温度夏天可能显示 29 度朋友却不知道晚上降温要加外套。我在实际脚本里会再解析一组today数据把最高温和最低温抓出来拼在推送消息里。字段选择上有一个建议宁可少拼一个字段不要为了凑齐所有数据去解析复杂表格。表格解析在页面改版时最容易崩而且一个字段崩了可能导致整个脚本报错。稳定的做法是抓两个区块当前天气和今日温度区间其他生活指数等字段能抓就抓抓不到就用默认值。抓取字段后应该先打印一次确认数据是想要的内容。如果你发现某个字段是空字符串不要急着调正则先打开页面看元素结构变了没。页面结构每变一次解析选择器就要跟着调整这是整个项目里维护频率最高的地方。3. 把天气塞进微信企业微信群机器人是当前最稳的路3.1 群机器人 webhook一分钟拿到的推送入口要给微信好友发消息最忌讳的是去用个人微信自动化方案。那些基于网页版微信的协议库常年封号而且现在很多账号已经无法登录网页版。真正稳定且官方支持的是企业微信群机器人拉一个群把好友都拉进来再添加一个群机器人它会给你一个 webhook 地址。你用脚本往这个地址 POST 一段 JSON就能把消息发到群里。有人会问这不是发到群里不是私聊吗实际使用里为了给“关心的好友”推送最轻量的方式就是建一个只有这几个人的群群名叫“天气小分队”每天早上机器人发一条。如果非要私聊可以用企业微信应用消息接口但那需要企业认证和应用配置复杂度高很多。对个人开发者和家庭场景群机器人已经够用这也是社区里最稳定的做法。创建机器人的步骤大概是在企业微信群里打开群设置找到“群机器人”点击“添加”给它起个名字生成 webhook。把 webhook 地址复制下来保存到你的配置文件或环境变量里。这个地址就像一把钥匙谁拿到谁就能往里发消息所以千万不要提交到公开仓库里。3.2 用 markdown 拼一条干净天气卡片企业微信群机器人支持文本和 markdown 两种格式。markdown 消息在微信里会渲染成带样式的小卡片比纯文本好看很多也适合放温度数据。需要注意群机器人的 markdown 语法是有限子集不支持复杂 HTML但支持加粗、字体颜色、引用和换行。import requests import json WEBHOOK_URL https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyreplace-me def send_weather(webhook: str, city: str, data: dict) - bool: msg ( f## {city}今日天气\n f 当前{data[temp]}℃ {data[weather]}\n f 湿度{data[humidity]}\n f 风力{data[wind]}\n f 今日{data[temp_low]}℃ ~ {data[temp_high]}℃\n ffont color\info\记得照顾好自己/font ) payload { msgtype: markdown, markdown: {content: msg} } resp requests.post(webhook, jsonpayload, timeout5) return resp.json().get(errcode) 0 if __name__ __main__: weather {temp: 23, weather: 多云, humidity: 55%, wind: 东南风3级, temp_low: 18, temp_high: 27} send_weather(WEBHOOK_URL, A城, weather)send_weather的返回值依赖于企业微信返回的errcode只有为 0 才算成功。这里我把超时设置为 5 秒因为推送失败可以重试但不要让定时任务一直挂在一个失败请求上。消息里的font colorinfo是企业微信 markdown 的专属写法不要换成标准 markdown 的颜色语法否则不会渲染。3.3 想私发给单个好友企业微信应用消息的替代方案如果你真的需要让每个好友各自收到私聊消息而不是群消息可以用企业微信的“客户联系”或“应用消息”。但代价比群机器人高不少你需要注册一个企业微信组织创建自建应用获取corpid、agentid和secret再通过 API 获取 access_token最后调用消息发送接口。整个流程对新手来说至少要折腾半天。从投入产出比看我不建议在第一个版本就做私聊推送。原因很简单群机器人十分钟上线私聊方案要先解决认证、用户关系、消息模板三件事。等群机器人跑了两个月确认稳定了再谈私有化通知。如果你只是给爸妈和三五好友推天气群消息完全够用他们反而能在群里聊起来。如果将来真要改造架构上只需要把send_weather的发送逻辑拿出来换一个发送函数即可前面的天气抓取代码完全不用动。这就是在写代码时把“抓取”和“推送”拆成两个函数的好处。4. 定时任务从手动跑到每天自动跑4.1 先用 APScheduler 在脚本内部定时早期调试阶段我不会直接挂到系统计划任务而是先在脚本里用 APScheduler 跑一次。它支持按固定时间触发比如每天早上07:30。好处是同一台机器上即使系统计划任务配置出错脚本内部仍然能自动触发适合在个人电脑上跑。from apscheduler.schedulers.blocking import BlockingScheduler def job(): weather fetch_weather(CITY_CODE) send_weather(WEBHOOK_URL, A城, weather) print(推送完成) scheduler BlockingScheduler(timezoneAsia/Shanghai) scheduler.add_job(job, triggercron, hour7, minute30, idweather_job) scheduler.start()timezone参数必须显式指定否则 APScheduler 会使用系统时区跨平台部署时会因为时区不同导致时间差八小时。add_job的id用来标识任务重复添加同 id 的任务会报错这在脚本被意外重复运行时很有用。这条代码运行后会阻塞主进程所以适合在后台挂机运行。4.2 部署到 Windows 计划任务APScheduler 虽然内部能定时但有一个致命弱点脚本必须一直保持运行。如果电脑重启或者 Python 进程被关掉任务就没了。所以正式部署还是建议交给系统。Windows 上最常用的是“任务计划程序”配置起来并不复杂。先写一个run_weather.py作为入口它不做任何其他事情只调用主任务函数并退出。然后在任务计划程序里新建任务触发器设为每天 07:30操作里“程序或脚本”填 Python 的完整路径“添加参数”填run_weather.py的完整路径“起始于”填脚本所在目录。这里最容易出错的是“起始于”字段如果为空脚本里用相对路径读取city.json会失败。我把任务配置成一个“即使上次运行失败也重复每 30 分钟运行一次”的规则防止某次抓取超时后整天的推送丢失。Windows 计划任务的“设置”选项卡里有“如果任务失败按以下频率重新启动”的选项设置成 30 分钟一次最多三次。这样你就不需要自己在代码里写重试循环。4.3 部署到 Linux crontab如果脚本跑在云服务器或树莓派上用 crontab 更直接。先确保run_weather.py可执行然后在 crontab 里写一行30 7 * * * cd /path/to/project /usr/bin/python3 run_weather.py weather.log 21这行的意思是每天 7:30 执行一次输出和错误都追加到weather.log。这里我建议用绝对路径包括cd的路径和 Python 解释器的路径因为 cron 环境里 PATH 很精简找不到python3很常见。 weather.log 21是为了保留日志后面排查问题全靠它。cron 的时区跟随系统如果你的服务器是 UTC 时区7:30 就会变成国内时间 15:30。需要先执行date查看系统时区如果不是国内时区建议在代码里把 APScheduler 的 timezone 固定为Asia/Shanghai或者直接改系统时区。我用的是后者因为 cron 对时区不敏感改系统时区更省心。5. 避坑指南定时抓天气发微信的五个常见坑5.1 推送里显示的永远是昨天的温度现象定时任务正常触发群里也收到了消息但温度明显和当天实时对不上。原因天气页面在某些时段只有缓存数据或者你解析的是“昨日温度”区块。还有可能是你在凌晨 0 点跑页面数据还没更新。解决第一把抓取时间调到早上 7 点后此时页面的今日数据已经更新第二在解析时打印原始数据确认你选中的元素的class或id到底属于哪个区块第三增加一个校验逻辑如果温度字段为空或等于昨天的值本次不推送并把日志打出来。5.2 定时任务到点不执行脚本手动跑完全正常现象在命令行里运行python run_weather.py没有任何问题但计划任务到时间不触发。原因Windows 计划任务里 Python 路径或工作目录配置错误cron 里脚本权限不够或者 Python 解释器使用了不同的环境缺少依赖包。解决先用系统的运行日志看任务是否被启动。在登录交互式运行改成“不管用户是否登录都要运行”的同时把“启动于”目录填绝对路径。Linux 上先用crontab -l确认任务已写入再在脚本第一行打印一个时间戳观察日志里是否有输出。5.3 webhook 请求频繁被限制现象有一天突然连续收到多条相同天气消息后来机器人不再发送提示errCode: 45009。原因你的脚本可能因异常启动了多个实例或者你测试时手动执行了多次脚本。企业微信群机器人有频率限制一分钟内最多发消息次数有限。解决在定时任务里加单实例锁。最简单的方式是脚本启动时尝试创建一个锁文件如果文件已存在则直接退出。同时给 webhook 请求加一个重试上限不要无限重发。日常调试用另一个机器人生产机器人只留给定时任务。5.4 城市代码失效导致推送失败现象抓取函数提醒raise_for_status报 404或者返回的页面结构里解析不出任何字段。原因天气网站调整了城市代码规则或者目标城市被合并到其他行政区划。解决不要依赖代码里的固定值把城市代码放进city.json并在抓取成功后校验温度字段是否存在于数据中。如果连续三天抓取失败让脚本发一条预警消息到自己的备用机器人提醒城市代码需要维护。这就是把错误当成数据来通知而不是只在日志里记录。5.5 推送消息里的 emoji 在 PC 微信上显示成方块现象手机上看到晴天符号正常在电脑版微信上却显示为一个小方块。原因PC 微信对部分 Unicode emoji 字体支持不全尤其是一些较新的天气符号。解决天气消息里不用 emoji 图标改用纯文字如“晴”“多云”“小雨”。如果一定要图形只使用微信内置的 markdown 引用线和字体颜色来区分重点。这也是为什么我的模板里只用了font color而没有加任何 emoji 的原因。6. 进阶在天气推送里加入穿衣建议和出行提醒6.1 根据温度区间生成建议文案推送消息里如果只有一串数字看多了会麻木。我在实际使用中会加一条温度建议低于 5 度提示“厚羽绒服”5 到 15 度提示“风衣或夹克”15 到 25 度提示“长袖或卫衣”25 度以上提示“短袖或裙子”。这个逻辑用一个简单的函数就能完成数据来自当天最高温。6.2 把密钥放进环境变量而不是写死在代码webhook 地址和城市代码属于敏感信息。我后来把WEBHOOK_URL改为从环境变量读取脚本里只做读取不写默认值。这样即使脚本被人看到对方也无法直接拿到推送入口。建议你也在.env文件里管理这些变量并用python-dotenv加载。6.3 从“能发”到“稳定发”一次完整的自测流程我给自己定的验收标准是连续跑七天不人工干预。第一周每天上午检查日志和群里消息确认推送时间、内容、样式都正常。如果某天漏发不是急着改重试而是先看是哪一环断了抓取、组装还是推送。把这一环修复后回放一次当天的数据确认修复有效。这个习惯帮我避免了很多“改了脚本但不知道自己有没有修好”的尴尬。最后我想说这个天气小工具最容易翻车的不是代码而是“跑两天就再也不想维护了”。我自己的经验是把它当成一个长期运行的小服务来对待该留日志就留日志该拆函数就拆函数。只要数据源和 webhook 都稳定它就能安安静静地替你关心人。希望这个方案能帮到你让你的问候比别人早到一步。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑