用Requests+BeautifulSoup实现天气预报数据采集:从入门到实战

在数据驱动的时代,天气预报数据是气象分析、农业规划、物流调度等场景的重要基础。本文将通过一个完整案例,教你如何用Python的Requests库获取网页内容,再用BeautifulSoup解析HTML,最终实现天气预报数据的自动化采集。整个过程不涉及复杂理论,只讲实战技巧,即使你是编程新手也能轻松上手。

一、为什么选择Requests+BeautifulSoup组合?

在Python爬虫领域,Scrapy框架功能强大但学习曲线陡峭,Selenium能处理动态页面但效率较低。对于天气预报这类结构化数据采集,Requests+BeautifulSoup的组合具有显著优势:

  1. 轻量高效:Requests负责HTTP请求,BeautifulSoup专注解析,两者配合内存占用小
  2. 开发快速:30行代码就能实现基础功能,适合快速验证需求
  3. 维护简单:代码可读性强,便于后续修改和扩展

以中国天气网为例,其省级天气页面采用标准HTML结构,非常适合用这种组合采集。我们以采集"北京市天气预报"为例,展示完整实现过程。

二、环境准备与基础代码

1. 安装必要库

复制代码
pip install requests beautifulsoup4 fake-useragent
  • requests:发送HTTP请求
  • beautifulsoup4:解析HTML
  • fake-useragent:生成随机User-Agent(反爬必备)

2. 基础请求代码

python 复制代码
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent

def get_weather_page(url):
    headers = {'User-Agent': UserAgent().random}
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 检查请求是否成功
        response.encoding = 'utf-8'  # 设置编码
        return response.text
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

# 测试请求
url = "http://www.weather.com.cn/textFC/hb.shtml"  # 华北地区天气
html_content = get_weather_page(url)
if html_content:
    print("获取页面成功")
复制代码
关键点说明:
  • 随机User-Agent模拟不同浏览器访问
  • 设置超时时间防止程序卡死
  • 统一编码避免中文乱码
  • 异常处理确保程序健壮性

三、HTML解析与数据提取

1. 分析页面结构

打开中国天气网华北地区页面,右键检查元素,找到天气数据所在的HTML结构:

xml 复制代码
<div class="conMidtab">
  <div class="conMidtab2">
    <table class="twoInner">
      <tr>
        <td class="time">08时</td>
        <td>晴</td>
        <td>-2℃</td>
        <td>3级</td>
      </tr>
      <!-- 更多行... -->
    </table>
  </div>
</div>

关键特征:

  • 天气数据在class="twoInner"的表格中
  • 每行数据包含时间、天气现象、温度、风力

2. 完整解析代码

复制代码
ini 复制代码
def parse_weather_data(html):
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.find('table', class_='twoInner')
    if not table:
        print("未找到天气表格")
        return []
    
    weather_data = []
    rows = table.find_all('tr')[1:]  # 跳过表头
    
    for row in rows:
        cols = row.find_all('td')
        if len(cols) >= 4:
            data = {
                'time': cols[0].get_text(strip=True),
                'weather': cols[1].get_text(strip=True),
                'temperature': cols[2].get_text(strip=True),
                'wind': cols[3].get_text(strip=True)
            }
            weather_data.append(data)
    
    return weather_data

# 测试解析
if html_content:
    data = parse_weather_data(html_content)
    for item in data[:3]:  # 打印前3条
        print(item)

输出示例

css 复制代码
{'time': '08时', 'weather': '晴', 'temperature': '-2℃', 'wind': '3级'}
{'time': '11时', 'weather': '晴', 'temperature': '3℃', 'wind': '2级'}
{'time': '14时', 'weather': '多云', 'temperature': '5℃', 'wind': '2级'}

3. 优化技巧

  • 容错处理 :检查table是否存在,避免程序崩溃
  • 数据清洗 :使用get_text(strip=True)去除空白字符
  • 结构化输出:将每行数据转为字典,便于后续处理

四、完整采集流程

将上述代码整合为完整脚本,并添加数据存储功能:

python 复制代码
import csv
from datetime import datetime

def save_to_csv(data, filename='weather.csv'):
    if not data:
        print("无数据可保存")
        return
    
    # 添加采集时间
    for item in data:
        item['update_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    
    # 写入CSV文件
    with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=data[0].keys())
        writer.writeheader()
        writer.writerows(data)
    print(f"数据已保存到 {filename}")

def main():
    url = "http://www.weather.com.cn/textFC/hb.shtml"
    html = get_weather_page(url)
    if html:
        data = parse_weather_data(html)
        save_to_csv(data)

if __name__ == '__main__':
    main()
复制代码
执行结果:

程序会在当前目录生成weather.csv文件,包含采集时间和所有天气数据。

五、进阶优化方向

1. 多城市采集

通过修改URL参数实现:

csharp 复制代码
CITIES = {
    '北京': 'hb.shtml',  # 华北
    '上海': 'hd.shtml',  # 华东
    # 添加更多城市...
}

def batch_collect():
    for city, path in CITIES.items():
        url = f"http://www.weather.com.cn/textFC/{path}"
        html = get_weather_page(url)
        if html:
            data = parse_weather_data(html)
            for item in data:
                item['city'] = city  # 添加城市字段
            save_to_csv(data, f'weather_{city.lower()}.csv')

2. 定时采集

使用schedule库实现每天8点自动采集:

scss 复制代码
import schedule
import time

def job():
    print("开始定时采集...")
    main()

schedule.every().day.at("08:00").do(job)

while True:
    schedule.run_pending()
    time.sleep(60)

3. 数据可视化

用Matplotlib简单绘制温度变化曲线:

scss 复制代码
import matplotlib.pyplot as plt

def plot_temperature(data):
    times = [item['time'] for item in data]
    temps = [int(item['temperature'].replace('℃', '')) for item in data]
    
    plt.figure(figsize=(10, 4))
    plt.plot(times, temps, marker='o')
    plt.title('北京今日温度变化')
    plt.xlabel('时间')
    plt.ylabel('温度(℃)')
    plt.grid(True)
    plt.savefig('temperature.png')
    plt.show()

六、常见问题Q&A

Q1:被网站封IP怎么办?

A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。更简单的方案是设置请求间隔:

python 复制代码
import time
import random

def safe_request(url):
    time.sleep(random.uniform(1, 3))  # 随机延迟1-3秒
    return get_weather_page(url)
复制代码
Q2:网站结构变了怎么办?

A:定期检查解析代码是否还能正常工作。建议:

  1. 将选择器(如class_='twoInner')提取为配置变量
  2. 添加页面结构校验逻辑
  3. 使用try-except捕获解析异常

Q3:如何采集动态加载的数据?

A:对于JavaScript渲染的数据,有两种方案:

  1. 分析接口:用浏览器开发者工具查找数据API(推荐)
  2. Selenium模拟:对复杂页面可使用Selenium+WebDriver

Q4:采集频率应该设置多少?

A:遵循robots.txt协议和网站服务条款。一般建议:

  • 公开数据:每小时不超过1次
  • 商业数据:联系网站获取授权
  • 添加随机延迟避免规律性请求

Q5:如何存储大量历史数据?

A:根据数据量选择:

  • 小规模:CSV/Excel
  • 中等规模:SQLite数据库
  • 大规模:MySQL/MongoDB等专业数据库

七、总结与展望

通过本文,你已掌握:

  1. 使用Requests发送HTTP请求
  2. 用BeautifulSoup解析HTML
  3. 提取结构化天气数据
  4. 存储和可视化数据
  5. 常见问题的解决方案

实际应用中,你可能需要处理:

  • 登录验证
  • 验证码识别
  • 分布式采集
  • 数据去重

建议从简单需求开始,逐步添加复杂功能。记住:爬虫开发的核心是模拟人类浏览行为,保持请求的随机性和合理性是长期运行的关键。

相关推荐
Draina1 小时前
CBC填充预言攻击-CBC Padding Oracle Crypto Attack
python·安全·web安全·网络安全·密码学·安全性测试
Angel Q.2 小时前
特征提取 | DINO 到 DINOv3
图像处理·python
不如语冰2 小时前
AI大模型入门-pytorch-张量2 tensor创建
python
NPE~2 小时前
[AI]Agent开发——ADK框架使用
人工智能·python·ai·教程·adk·agent开发
矮个史蒂芬2 小时前
统计verilog .v文件中output 的bit数
python
gwf2163 小时前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
爱吃提升3 小时前
python 分布式爬虫、爬虫合规与综合实战项目
分布式·爬虫·python
审小匠OpenCPAi3 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
元Y亨H4 小时前
Pandas 解析 Excel 导致的内存溢出(MemoryError)
python·excel
金銀銅鐵5 小时前
[Python] 用 turtle 来绘制瑞典国旗
python