你相不相信只需要30行代码,就能把网页上的原始数据变成酷炫的图表?今天咱们就要用Python爬虫+数据可视化的组合拳,把枯燥的数字变成会说话的图形!(手痒了吗?)
咱们拿「天气网」开刀(学习用途,非商用),目标:抓取北京最近7天的天气数据。注意这个反爬机制:必须带上User-Agent头!!!
import requests
from bs4 import BeautifulSoup
url = 'http://www.weather.com.cn/weather/101010100.shtml'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')
用CSS选择器精准抓取数据节点,这里有个坑:日期藏在title属性里(开发者工具大法好)
weather_data = []
items = soup.select('li.sky')
for item in items:
date = item.h1.get('title').split(' ')[0]
temp = item.select('.tem')[0].text.strip().replace('\n', '')
weather = item.select('.wea')[0].text
wind = item.select('.win i')[0].text
weather_data.append({
'日期': date,
'温度': temp,
'天气': weather,
'风力': wind
})
原始数据长这样:“高温 28℃/低温 18℃”,咱们要拆分成两个字段:
import pandas as pd
df = pd.DataFrame(weather_data)
df[['最高温', '最低温']] = df['温度'].str.extract('(\d+)℃/(\d+)℃')
df['最高温'] = df['最高温'].astype(int)
df['最低温'] = df['最低温'].astype(int)
用正则表达式提取数字部分:
df['风力等级'] = df['风力'].str.extract('(\d+)-?\d*级').astype(float)
先来个温度变化趋势图(Matplotlib常规操作):
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.plot(df['日期'], df['最高温'], marker='o', label='最高温')
plt.plot(df['日期'], df['最低温'], marker='s', label='最低温')
plt.title('北京七日温度变化曲线')
plt.xlabel('日期')
plt.ylabel('温度(℃)')
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.show()
用Seaborn展示温度与风力的关系(装逼必备):
import seaborn as sns
plt.figure(figsize=(8,6))
heatmap_data = df.pivot_table(values='最高温',
index='风力等级',
columns='天气')
sns.heatmap(heatmap_data, annot=True, cmap='coolwarm')
plt.title('天气类型与温度关系热力图')
plt.show()
上Pyecharts做交互式图表(效果炸裂):
from pyecharts.charts import Line
from pyecharts import options as opts
line = (
Line()
.add_xaxis(df['日期'].tolist())
.add_yaxis("最高温", df['最高温'].tolist())
.add_yaxis("最低温", df['最低温'].tolist())
.set_global_opts(
title_opts=opts.TitleOpts(title="北京温度走势"),
toolbox_opts=opts.ToolboxOpts(),
datazoom_opts=[opts.DataZoomOpts()]
)
)
line.render('temperature.html')
反爬突破技巧:遇到403错误时,试试加上:
headers['Referer'] = '同域名下的其他页面URL'
数据缺失处理:用Pandas的fillna方法:
df['风力等级'] = df['风力等级'].fillna(df['风力等级'].mean())
可视化优化诀窍:
linestyle='--'
color=plt.cm.viridis(np.linspace(0,1,len(df)))
老规矩,代码已上传到我的GitHub仓库(项目名weather-visualization),需要的小伙伴可以自取。不过更建议自己动手敲一遍代码,毕竟__复制粘贴学不会真本事__!!!
爬虫+可视化这个组合就像火锅配冰啤酒——越搭越上头!刚开始可能会被反爬机制搞到崩溃,但突破之后那种爽感,就跟游戏通关一样带劲。记住:每个报错信息都是进步的阶梯,遇到问题先看错误日志,再查文档,最后才是问谷歌。
(下次想看我折腾哪个网站?评论区见!)