1. 项目概述与核心价值
天气预报+微信推送这个组合看似简单,实则暗藏玄机。作为一个经常需要关注天气情况的程序员,我发现市面上现成的天气推送服务要么功能过剩,要么定制化不足。而用Python自己搭建一个,不仅能精准控制推送内容和时间,还能在这个过程中掌握爬虫和微信接口的核心技术点。
这个项目最吸引人的地方在于它的"30分钟"承诺——通过精心设计的代码结构和合理的工具选型,确实可以在半小时内完成从数据获取到消息推送的全流程。但要注意,这里的"30分钟"是指核心功能跑通的时间,如果要做到稳定运行和异常处理,还需要额外投入一些精力。
2. 环境准备与工具选型
2.1 Python环境配置
建议使用Python 3.7+版本,这个项目对Python版本要求不高,但需要注意几个关键库的兼容性:
bash复制# 创建虚拟环境(推荐)
python -m venv weather_bot
source weather_bot/bin/activate # Linux/Mac
weather_bot\Scripts\activate # Windows
# 安装核心依赖
pip install requests beautifulsoup4 itchat
注意:itchat库在Python 3.9+可能会有兼容性问题,如果遇到报错可以考虑使用wxpy或wechatpy等替代方案
2.2 天气数据源选择
经过实测对比,以下几个天气API比较适合本项目:
- 中国天气网(免费但需要处理HTML)
- 和风天气(有免费API额度)
- OpenWeatherMap(国际数据,需要注册)
考虑到国内访问稳定性和数据格式友好度,本教程选用中国天气网的HTML版作为数据源,虽然需要解析HTML,但胜在稳定免费。
3. 爬虫核心实现
3.1 网页分析与数据定位
首先打开中国天气网的城市页面(如北京:http://www.weather.com.cn/weather/101010100.shtml),通过浏览器开发者工具查看HTML结构:
python复制import requests
from bs4 import BeautifulSoup
def get_weather(city_code='101010100'):
url = f'http://www.weather.com.cn/weather/{city_code}.shtml'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'html.parser')
# 定位天气数据
weather_data = soup.find('ul', class_='t clearfix').find_all('li')
today = weather_data[0]
# 提取关键信息
date = today.find('h1').text
weather = today.find('p', class_='wea').text
temp = today.find('p', class_='tem').text.strip()
wind = today.find('p', class_='win').find('i').text
return f"{date}天气:{weather},温度:{temp},风力:{wind}"
except Exception as e:
return f"获取天气失败:{str(e)}"
3.2 反爬虫策略应对
中国天气网虽然没有严格的防爬措施,但为了做一个负责任的爬虫使用者,我们应该:
- 设置合理的请求间隔(至少5秒一次)
- 使用随机User-Agent
- 遵守robots.txt规则
- 缓存已获取的数据,避免重复请求
python复制from time import sleep
import random
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15',
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15'
]
def get_with_retry(url, max_retry=3):
for i in range(max_retry):
try:
headers = {'User-Agent': random.choice(USER_AGENTS)}
response = requests.get(url, headers=headers, timeout=10)
sleep(5 + random.random()*3) # 随机延迟5-8秒
return response
except:
if i == max_retry - 1:
raise
sleep(10)
4. 微信消息推送实现
4.1 微信登录与消息发送
使用itchat库实现微信消息推送:
python复制import itchat
def wechat_login():
itchat.auto_login(hotReload=True, statusStorageDir='wx_weather.pkl')
print("登录成功!")
def send_weather_to_friend(weather_info, friend_remark='天气小助手'):
try:
friend = itchat.search_friends(remarkName=friend_remark)
if friend:
itchat.send(weather_info, toUserName=friend[0]['UserName'])
print("消息发送成功!")
else:
print("未找到指定好友")
except Exception as e:
print(f"发送失败:{str(e)}")
4.2 定时推送实现
要实现每日定时推送,可以使用Python的schedule库:
python复制import schedule
import time
def job():
weather = get_weather()
send_weather_to_friend(weather)
# 设置每天早上7点推送
schedule.every().day.at("07:00").do(job)
if __name__ == '__main__':
wechat_login()
while True:
schedule.run_pending()
time.sleep(60) # 每分钟检查一次
5. 项目优化与扩展
5.1 异常处理与日志记录
一个健壮的系统需要完善的异常处理和日志记录:
python复制import logging
from datetime import datetime
logging.basicConfig(
filename='weather_bot.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def safe_job():
try:
start_time = datetime.now()
weather = get_weather()
send_weather_to_friend(weather)
duration = (datetime.now() - start_time).total_seconds()
logging.info(f"任务执行成功,耗时{duration:.2f}秒")
except Exception as e:
logging.error(f"任务执行失败:{str(e)}")
5.2 多城市支持与数据存储
扩展支持多个城市的天气查询,并使用SQLite存储历史数据:
python复制import sqlite3
CITY_CODES = {
'北京': '101010100',
'上海': '101020100',
'广州': '101280101'
}
def init_db():
conn = sqlite3.connect('weather.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS weather_log
(city text, date text, weather text, temp text, wind text, created_at timestamp)''')
conn.commit()
conn.close()
def save_weather(city, weather_info):
conn = sqlite3.connect('weather.db')
c = conn.cursor()
c.execute("INSERT INTO weather_log VALUES (?,?,?,?,?,?)",
(city, datetime.now().strftime('%Y-%m-%d'), *weather_info.split(','), datetime.now()))
conn.commit()
conn.close()
6. 部署与长期运行方案
6.1 本地长期运行方案
对于Windows用户,可以将脚本转换为后台服务:
- 将脚本保存为
weather_bot.py - 创建批处理文件
run_bot.bat:
bat复制@echo off
python weather_bot.py
pause
- 使用Windows任务计划程序设置开机启动
6.2 服务器部署方案
对于Linux服务器,可以使用systemd创建服务:
- 创建服务文件
/etc/systemd/system/weather_bot.service:
ini复制[Unit]
Description=Weather WeChat Bot
After=network.target
[Service]
User=root
WorkingDirectory=/path/to/your/script
ExecStart=/usr/bin/python3 /path/to/your/script/weather_bot.py
Restart=always
[Install]
WantedBy=multi-user.target
- 启用并启动服务:
bash复制sudo systemctl enable weather_bot
sudo systemctl start weather_bot
7. 常见问题与解决方案
7.1 微信登录问题
itchat登录可能会遇到以下问题:
- 二维码无法显示:确保服务器有图形界面或使用控制台二维码
- 登录状态失效:设置hotReload=True并指定statusStorageDir
- 账号限制:新注册的微信号可能有发送限制
7.2 天气数据获取失败
常见原因及解决方案:
- IP被封:更换IP或使用代理
- HTML结构变化:及时更新解析逻辑
- 网络问题:增加重试机制和超时设置
7.3 推送内容优化建议
为了让推送更有价值,可以考虑:
- 添加生活指数(穿衣、运动等)
- 加入温馨提醒(如雨天带伞)
- 格式化消息内容,使用emoji增加可读性
我在实际使用中发现,早上7-8点推送的打开率最高,而内容简洁明了(不超过3行)的消息最受欢迎。另外,建议在代码中加入心跳检测机制,定期给自己发送状态报告,确保服务正常运行。
