用Python构建旅游天气数据采集系统从爬虫到数据库全流程解析每次旅行前你是否会花大量时间在各个天气网站反复查询目的地未来一周的预报去年我计划一次多城市旅行时发现手动收集10个城市的历史天气数据简直是一场噩梦——不同网站格式不统一、数据分散、无法批量导出。这就是为什么我决定用Python开发一个自动化天气数据采集系统今天就把这个实战项目的完整思路和代码分享给你。1. 项目规划与环境准备1.1 明确数据需求一个实用的旅游天气数据系统需要包含以下核心字段字段类别具体字段说明基础信息城市、日期数据主键温度数据最高气温、最低气温摄氏度单位气象状况天气状况、风向风力文本描述衍生指标体感温度、降水概率可选扩展1.2 开发环境配置推荐使用conda创建独立Python环境conda create -n weather_spider python3.8 conda activate weather_spider pip install requests beautifulsoup4 pymysql pandas提示建议使用PyCharm或VS Code作为IDE它们对Python项目管理和调试支持更好2. 网页爬取核心实现2.1 目标网站分析技巧以中国天气网为例按F12打开开发者工具后重点关注Network面板观察数据加载方式静态HTML或API接口Elements面板使用选择器工具定位数据节点Console面板测试XPath或CSS选择器表达式import requests from bs4 import BeautifulSoup headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def get_city_list(): url http://www.weather.com.cn/china/ resp requests.get(url, headersheaders) soup BeautifulSoup(resp.text, html.parser) return [a[href] for a in soup.select(.lqcontentBoxTab a)][:10]2.2 反爬虫策略应对方案常见防护手段及破解方法User-Agent检测随机轮换头部信息请求频率限制添加time.sleep(random.uniform(1,3))IP封禁使用代理IP池需谨慎遵守网站规则验证码调用打码平台或机器学习识别from fake_useragent import UserAgent import random import time ua UserAgent() headers {User-Agent: ua.random} def safe_request(url): try: time.sleep(random.uniform(1, 3)) return requests.get(url, headersheaders) except Exception as e: print(f请求失败: {e}) return None3. 数据解析与清洗3.1 BeautifulSoup高级用法解析历史天气数据页面时这些技巧很实用多层嵌套选择soup.select(div.content ul li)属性过滤soup.find_all(div, class_temp)正则匹配re.compile(r\d℃)def parse_weather(html): soup BeautifulSoup(html, html.parser) data [] for day in soup.select(.t.clearfix li): date day.select_one(.time).get_text() high_temp day.select_one(.tem span).get_text() low_temp day.select_one(.tem i).get_text() weather day.select_one(.wea).get_text() data.append([date, high_temp, low_temp, weather]) return pd.DataFrame(data)3.2 数据标准化处理原始数据常见问题及处理方法温度单位统一去除℃符号转为数值日期格式转换pd.to_datetime(df[日期])异常值处理df.replace(--, np.nan)文本规范化df[天气].str.replace(转, /)4. 数据存储与可视化4.1 MySQL数据库设计创建适合天气数据的表结构CREATE TABLE city_weather ( id int(11) NOT NULL AUTO_INCREMENT, city varchar(20) NOT NULL, date date NOT NULL, high_temp float DEFAULT NULL, low_temp float DEFAULT NULL, weather varchar(50) DEFAULT NULL, wind varchar(50) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY city_date (city,date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;Python操作MySQL的最佳实践import pymysql def save_to_mysql(df, table_name): conn pymysql.connect( hostlocalhost, userroot, passwordyourpassword, dbweather_db ) try: with conn.cursor() as cursor: for _, row in df.iterrows(): sql fINSERT INTO {table_name} VALUES (%s,%s,%s,%s,%s) cursor.execute(sql, tuple(row)) conn.commit() finally: conn.close()4.2 基础可视化分析使用Pandas和Matplotlib快速生成洞察def plot_temperature_trend(df): plt.figure(figsize(12,6)) df[date] pd.to_datetime(df[date]) df.set_index(date)[[high_temp,low_temp]].plot() plt.title(城市温度变化趋势) plt.ylabel(温度(℃)) plt.grid(True) plt.show()5. 项目扩展与优化方向5.1 系统健壮性提升异常处理机制网络中断、数据格式异常等场景日志记录系统使用logging模块记录运行状态断点续爬功能记录已采集的城市/日期5.2 进阶功能实现多线程采集使用concurrent.futures加速数据自动更新设置定时任务crontab或APSchedulerRESTful API用Flask暴露数据接口预警系统当出现极端天气时发送邮件通知from concurrent.futures import ThreadPoolExecutor def multi_thread_crawl(city_urls): with ThreadPoolExecutor(max_workers5) as executor: results list(executor.map(crawl_single_city, city_urls)) return pd.concat(results)这个项目最让我惊喜的是原本需要数小时手动收集的数据现在只需运行脚本5分钟就能获取。在实际使用中建议将城市列表改为配置文件这样非技术人员也能轻松修改采集目标。
手把手教你用Python爬取10个旅游城市天气数据(Requests+BeautifulSoup实战)
用Python构建旅游天气数据采集系统从爬虫到数据库全流程解析每次旅行前你是否会花大量时间在各个天气网站反复查询目的地未来一周的预报去年我计划一次多城市旅行时发现手动收集10个城市的历史天气数据简直是一场噩梦——不同网站格式不统一、数据分散、无法批量导出。这就是为什么我决定用Python开发一个自动化天气数据采集系统今天就把这个实战项目的完整思路和代码分享给你。1. 项目规划与环境准备1.1 明确数据需求一个实用的旅游天气数据系统需要包含以下核心字段字段类别具体字段说明基础信息城市、日期数据主键温度数据最高气温、最低气温摄氏度单位气象状况天气状况、风向风力文本描述衍生指标体感温度、降水概率可选扩展1.2 开发环境配置推荐使用conda创建独立Python环境conda create -n weather_spider python3.8 conda activate weather_spider pip install requests beautifulsoup4 pymysql pandas提示建议使用PyCharm或VS Code作为IDE它们对Python项目管理和调试支持更好2. 网页爬取核心实现2.1 目标网站分析技巧以中国天气网为例按F12打开开发者工具后重点关注Network面板观察数据加载方式静态HTML或API接口Elements面板使用选择器工具定位数据节点Console面板测试XPath或CSS选择器表达式import requests from bs4 import BeautifulSoup headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def get_city_list(): url http://www.weather.com.cn/china/ resp requests.get(url, headersheaders) soup BeautifulSoup(resp.text, html.parser) return [a[href] for a in soup.select(.lqcontentBoxTab a)][:10]2.2 反爬虫策略应对方案常见防护手段及破解方法User-Agent检测随机轮换头部信息请求频率限制添加time.sleep(random.uniform(1,3))IP封禁使用代理IP池需谨慎遵守网站规则验证码调用打码平台或机器学习识别from fake_useragent import UserAgent import random import time ua UserAgent() headers {User-Agent: ua.random} def safe_request(url): try: time.sleep(random.uniform(1, 3)) return requests.get(url, headersheaders) except Exception as e: print(f请求失败: {e}) return None3. 数据解析与清洗3.1 BeautifulSoup高级用法解析历史天气数据页面时这些技巧很实用多层嵌套选择soup.select(div.content ul li)属性过滤soup.find_all(div, class_temp)正则匹配re.compile(r\d℃)def parse_weather(html): soup BeautifulSoup(html, html.parser) data [] for day in soup.select(.t.clearfix li): date day.select_one(.time).get_text() high_temp day.select_one(.tem span).get_text() low_temp day.select_one(.tem i).get_text() weather day.select_one(.wea).get_text() data.append([date, high_temp, low_temp, weather]) return pd.DataFrame(data)3.2 数据标准化处理原始数据常见问题及处理方法温度单位统一去除℃符号转为数值日期格式转换pd.to_datetime(df[日期])异常值处理df.replace(--, np.nan)文本规范化df[天气].str.replace(转, /)4. 数据存储与可视化4.1 MySQL数据库设计创建适合天气数据的表结构CREATE TABLE city_weather ( id int(11) NOT NULL AUTO_INCREMENT, city varchar(20) NOT NULL, date date NOT NULL, high_temp float DEFAULT NULL, low_temp float DEFAULT NULL, weather varchar(50) DEFAULT NULL, wind varchar(50) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY city_date (city,date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;Python操作MySQL的最佳实践import pymysql def save_to_mysql(df, table_name): conn pymysql.connect( hostlocalhost, userroot, passwordyourpassword, dbweather_db ) try: with conn.cursor() as cursor: for _, row in df.iterrows(): sql fINSERT INTO {table_name} VALUES (%s,%s,%s,%s,%s) cursor.execute(sql, tuple(row)) conn.commit() finally: conn.close()4.2 基础可视化分析使用Pandas和Matplotlib快速生成洞察def plot_temperature_trend(df): plt.figure(figsize(12,6)) df[date] pd.to_datetime(df[date]) df.set_index(date)[[high_temp,low_temp]].plot() plt.title(城市温度变化趋势) plt.ylabel(温度(℃)) plt.grid(True) plt.show()5. 项目扩展与优化方向5.1 系统健壮性提升异常处理机制网络中断、数据格式异常等场景日志记录系统使用logging模块记录运行状态断点续爬功能记录已采集的城市/日期5.2 进阶功能实现多线程采集使用concurrent.futures加速数据自动更新设置定时任务crontab或APSchedulerRESTful API用Flask暴露数据接口预警系统当出现极端天气时发送邮件通知from concurrent.futures import ThreadPoolExecutor def multi_thread_crawl(city_urls): with ThreadPoolExecutor(max_workers5) as executor: results list(executor.map(crawl_single_city, city_urls)) return pd.concat(results)这个项目最让我惊喜的是原本需要数小时手动收集的数据现在只需运行脚本5分钟就能获取。在实际使用中建议将城市列表改为配置文件这样非技术人员也能轻松修改采集目标。