1. 项目概述:Python爬虫抓取天气数据实战
这个项目适合刚接触Python爬虫的新手,通过Requests和BeautifulSoup这两个经典库的组合,快速实现一个能抓取公开天气数据的实用脚本。我选择天气数据作为案例有三个原因:一是数据源稳定且结构清晰;二是避免了涉及敏感信息的风险;三是结果可视化直观,能立即看到爬取成效。
作为从业8年的爬虫开发者,我见过太多新手一上来就挑战复杂网站,结果被反爬机制打击信心。这个10分钟入门的案例特意选择了对新手友好的数据源,你将学到:如何用Requests模拟浏览器请求、用BeautifulSoup解析HTML结构、处理常见的网络异常,以及遵守robots.txt的爬虫礼仪。
2. 核心工具与技术解析
2.1 Requests库的核心作用
Requests是Python最流行的HTTP客户端库,相比原生urllib3有更简洁的API。在这个项目中我们主要用到:
python复制import requests
response = requests.get(url, headers=headers, timeout=5)
关键参数说明:
- headers:需要模拟浏览器User-Agent,例如:
python复制headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
- timeout:必须设置超时(建议3-5秒),避免长时间卡死
注意:实际项目中要控制请求频率,添加随机延迟(如time.sleep(random.uniform(1,3))),否则可能触发429 Too Many Requests错误
2.2 BeautifulSoup的解析技巧
BeautifulSoup将复杂HTML转换为树形结构,常用方法:
python复制from bs4 import BeautifulSoup
soup = BeautifulSoup(html_text, 'lxml') # 推荐用lxml解析器
temp = soup.select_one('.current-temp').text # CSS选择器定位
经验之谈:
- 优先使用CSS选择器(select/select_one),比find/find_all更直观
- 遇到动态加载数据时,需要检查Network面板找真实API
- 用prettify()方法可以格式化查看HTML结构
3. 完整实现步骤详解
3.1 确定目标数据源
选择中国天气网(www.weather.com.cn)的公开数据为例:
- 城市选择页面:http://www.weather.com.cn/weather1d/101010100.shtml
- 数据特征:
- 当前温度:class="tem"下的span标签
- 天气状况:class="wea"的title属性
- 风力风向:class="win"下的span文本
3.2 编写爬虫脚本
完整代码示例:
python复制import requests
from bs4 import BeautifulSoup
import time
import random
def get_weather(city_code):
url = f"http://www.weather.com.cn/weather1d/{city_code}.shtml"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
try:
response = requests.get(url, headers=headers, timeout=5)
response.raise_for_status() # 检查HTTP状态码
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
weather = {
'temp': soup.select_one('.tem span').text + '℃',
'condition': soup.select_one('.wea')['title'],
'wind': soup.select_one('.win i').text
}
return weather
except Exception as e:
print(f"抓取失败: {str(e)}")
return None
# 示例:获取北京天气(城市代码101010100)
print(get_weather('101010100'))
time.sleep(random.uniform(1, 3)) # 礼貌性延迟
3.3 关键环节说明
- 异常处理:必须包含try-except块,处理网络超时、解析失败等情况
- 编码设置:中文字符集需要显式指定为utf-8
- 延迟策略:在循环抓取时,建议使用指数退避算法处理失败重试
4. 常见问题与优化方案
4.1 反爬虫应对策略
当遇到403/429状态码时,可以尝试:
- 轮换User-Agent列表
- 添加Referer等合法请求头
- 使用session保持会话
python复制session = requests.Session()
session.headers.update({'Referer': 'http://www.weather.com.cn/'})
4.2 数据存储扩展
建议将结果保存为结构化数据:
python复制import csv
def save_to_csv(data, filename):
with open(filename, 'a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=data.keys())
if f.tell() == 0: # 如果是空文件才写表头
writer.writeheader()
writer.writerow(data)
4.3 遵守爬虫道德规范
- 检查robots.txt(如www.weather.com.cn/robots.txt)
- 控制请求频率(建议≥3秒/次)
- 不抓取敏感/隐私数据
- 设置明显的爬虫标识(如Contact头字段)
5. 项目进阶方向
掌握基础爬取后,可以尝试:
- 多城市并发抓取(使用concurrent.futures线程池)
- 定时任务调度(结合APScheduler库)
- 数据可视化(用Matplotlib绘制温度曲线)
- 异常监控(通过日志记录失败情况)
我在实际项目中总结出一个经验:刚开始应该先用少量请求测试网站响应,确认没问题再扩大规模。曾经有个新手一次性发起上千请求,导致IP被封,这个教训值得警惕。
