Python与Pandas,数据分析以及爬虫技术统计历史天气

论坛 期权论坛 期权     
Python学习交流乐园   2019-7-21 15:26   6221   0
[h1]背景[/h1]最近在计划明年从北京rebase到深圳去,所以最近在看深圳的各个方面。去年在深圳呆过一段时间,印象最深的是,深圳总是突然就下雨,还下好大的雨。对于我这种从小在南方长大但是后面又在北京呆了2年多的人来说,熟悉而又无奈。



[h3]当然在学习Python的道路上肯定会困难,没有好的学习资料,怎么去学习呢?学习Python中有不明白推荐加入交流群号:790921645 群里有志同道合的小伙伴,互帮互助, 群里有不错的视频学习教程和PDF![/h3]
今天早上本来想随便浏览浏览一个天气网站,看看深圳的历史天气如何的,但是,一不小心发现,这家网站竟然直接能用API来抓数据,这~~~还不抓一波,省的自己一个月一个月地看。
先上最后的效果图:


所有的code都在我的GitHub上:boydfd
下面从几个方面讲一讲我是怎么做的:
  • 爬取数据
  • 用pandas显示数据
  • 功能扩展
  • 遇到的坑
[h1]爬取数据[/h1]先是在http://tianqi.2345.com上面浏览了一下深圳的6月份天气。然后发现点切换月份的时候,网址没有变,那应该有请求API吧,看看这个API长啥样吧。



发现返回值就是纯JS代码,那就解析一下吧:
  • 去掉
    1. var =
    复制代码
    和最后的
    1. ;
    复制代码

  • 用到
    1. demjson
    复制代码
    解析成Python的
    1. List[Dict]
    复制代码
    对象。
  • 转成pandas的
    1. DataFrame
    复制代码
  • 加上我们的date字段
date = '201905'weather = requests.get('http://tianqi.2345.com/t/wea_history/js/{date}/59493_{date}.js'.format(date=date)).text.split('=')[1][:-1]weather = demjson.decode(weather)['tqInfo']df = pd.DataFrame(weather)df['month'] = date结果是这样的:


[h1]用Pandas显示数据[/h1][h2]太多雨天[/h2]我们可以看到,有各种雷阵雨啊,阴转雨啊,雨转阴之类的,这样看到的天气太杂了,所以我就统一了一下,按照雨、多云、阴、晴的顺序来排序,先出出现的关键词优先级更高。
写一个函数来处理之:
rain = '雨'rain_index = ' ' + raincloudy = '多云'cloudy_index = ' ' + cloudyovercast = '阴'overcast_index = ' ' + overcastsunny = '晴'sunny_index = ' ' + sunnydef weath_category(row):    tianqi = row['tianqi']    if tianqi.find(rain) != -1:        return rain_index    if tianqi.find(overcast) != -1:        return overcast_index    if tianqi.find(cloudy) != -1:        return cloudy_index    return sunny_index[h2]多个月的数据[/h2]一个月的数据不够啊,我们想要很多个月的数据,那就写得函数来生成月份吧。
def date_generate(start, end):    start = datetime.strptime(start, '%Y%m')    end = datetime.strptime(end, '%Y%m')    while True:        next_start = start + relativedelta(months=1)        yield start.strftime('%Y%m')        if next_start > end:            break        start = next_start[h2]画图[/h2]分好类,爬了多个月份的数据,就剩最终的画图部分了。使用Pandas提供给我们的函数,可以很容易就画出图来。
def plot_weather(start, end):    df = read_weather(start, end).dropna().reset_index()    df['weather'] = df.apply(weath_category, axis=1)        from pylab import rcParams    rcParams['figure.figsize'] = 40, 10    weather_df = df.groupby(['month', 'weather']).aqi.count().unstack().reset_index()    weather_df.plot.bar(x='month', y=[rain_index, overcast_index, cloudy_index, sunny_index])

[h1]功能扩展[/h1]现在只能收集到一个月的数据,想收集多个月的数据,还都自己去页面上找城市代表的code是啥,太低效了。
这个网站这么容易爬,那就再试试能不能找到调用code的API。
啊哦,一不小心找到了所有的code,哈哈哈。



那就在JS里面提取一下。
  • 先把所有的JS代码都复制到浏览器的console里, 结果长这样:

  • 将其转换成字符串。
provqx.flatMap(a => a).join('|')
  • 在Python里处理它。
def line_to_city_code(line):    return line.split(' ')[1].split('-')def get_city_to_code():    city_code_list = list(map(line_to_city_code, city_code.split('|')))    return {city_code[0]: city_code[1] for city_code in city_code_list if len(city_code) == 2}这样我们就拿到所有的code了,只需要输入城市,开始时间,结束时间,一张漂亮的图就出来了,我还写了个类稍微封装了一下,只需要这样就能使用了:
Weather('深圳').plot_weather('201701', '201906')
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:20
帖子:4
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP