背景

最近在计划明年从北京rebase到深圳去,所以最近在看深圳的各个方面。去年在深圳呆过一段时间,印象最深的是,深圳总是突然就下雨,还下好大的雨。对于我这种从小在南方长大但是后面又在北京呆了2年多的人来说,熟悉而又无奈。

今天早上本来想随便浏览浏览一个天气网站,看看深圳的历史天气如何的,但是,一不小心发现,这家网站竟然直接能用API来抓数据,这~~~还不抓一波,省的自己一个月一个月地看。

先上最后的效果图:

所有的code都在我的GitHub上:boydfd

下面从几个方面讲一讲我是怎么做的:

  1. 爬取数据
  2. 用pandas显示数据
  3. 功能扩展
  4. 遇到的坑

爬取数据

先是在http://tianqi.2345.com上面浏览了一下深圳的6月份天气。然后发现点切换月份的时候,网址没有变,那应该有请求API吧,看看这个API长啥样吧。

发现返回值就是纯JS代码,那就解析一下吧:

  1. 去掉var =和最后的;
  2. 用到demjson解析成Python的List[Dict]对象。
  3. 转成pandas的DataFrame
  4. 加上我们的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

结果是这样的:

用Pandas显示数据

太多雨天

我们可以看到,有各种雷阵雨啊,阴转雨啊,雨转阴之类的,这样看到的天气太杂了,所以我就统一了一下,按照雨、多云、阴、晴的顺序来排序,先出出现的关键词优先级更高。

写一个函数来处理之:

rain = '雨'
rain_index = ' ' + rain
cloudy = '多云'
cloudy_index = ' ' + cloudy
overcast = '阴'
overcast_index = ' ' + overcast
sunny = '晴'
sunny_index = ' ' + sunny
def 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

多个月的数据

一个月的数据不够啊,我们想要很多个月的数据,那就写得函数来生成月份吧。

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

画图

分好类,爬了多个月份的数据,就剩最终的画图部分了。使用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])

功能扩展

现在只能收集到一个月的数据,想收集多个月的数据,还都自己去页面上找城市代表的code是啥,太低效了。

这个网站这么容易爬,那就再试试能不能找到调用code的API。

啊哦,一不小心找到了所有的code,哈哈哈。

那就在JS里面提取一下。

  1. 先把所有的JS代码都复制到浏览器的console里, 结果长这样:

  1. 将其转换成字符串。
provqx.flatMap(a => a).join('|')
  1. 在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')

遇到的坑

以前在电脑里面处理过一次,就是matplotlib画图中文乱码的事情,这次换了新电脑又碰到了。所以又搞了一次,

大概的步骤可以参考https://www.jianshu.com/p/8ed59ac76c06

我为了以防下次再经历一次,就写了个脚本自动处理这件事,目前只支持macOS和Python3。

脚本也在我的GitHub:bash

直接执行下面的bash脚本就可以解决这个问题:

curl -o- https://raw.githubusercontent.com/boydfd/one_step_solve/master/matplotlib_chinese.sh | bash

用Python和Pandas以及爬虫技术统计历史天气的更多相关文章

  1. python+tkinter+动画图片+爬虫(查询天气)的GUI图形界面设计

    1.完整代码: import time import urllib.request #发送网络请求,获取数据 import gzip #压缩和解压缩模块 import json #解析获得的数据 fr ...

  2. Python 爬虫+tkinter界面 实现历史天气查询

    文章目录 一.实现效果 1. python代码 2. 运行效果 二.基本思路 1. 爬虫部分 2. tkinter界面 一.实现效果 很多人学习python,不知道从何学起.很多人学习python,掌 ...

  3. Python初学者之网络爬虫(二)

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...

  4. python 爬取历史天气

    python 爬取历史天气 官网:http://lishi.tianqi.com/luozhuangqu/201802.html # encoding:utf-8 import requests fr ...

  5. 用Python的Pandas和Matplotlib绘制股票KDJ指标线

    我最近出了一本书,<基于股票大数据分析的Python入门实战 视频教学版>,京东链接:https://item.jd.com/69241653952.html,在其中给出了MACD,KDJ ...

  6. 【Python】:简单爬虫作业

    使用Python编写的图片爬虫作业: #coding=utf-8 import urllib import re def getPage(url): #urllib.urlopen(url[, dat ...

  7. 使用python/casperjs编写终极爬虫-客户端App的抓取-ZOL技术频道

    使用python/casperjs编写终极爬虫-客户端App的抓取-ZOL技术频道 使用python/casperjs编写终极爬虫-客户端App的抓取

  8. [Python学习] 简单网络爬虫抓取博客文章及思想介绍

            前面一直强调Python运用到网络爬虫方面很有效,这篇文章也是结合学习的Python视频知识及我研究生数据挖掘方向的知识.从而简介下Python是怎样爬去网络数据的,文章知识很easy ...

  9. Python爬虫入门教程 53-100 Python3爬虫获取三亚天气做旅游参照

    爬取背景 这套课程虽然叫爬虫入门类课程,但是里面涉及到的点是非常多,十分检验你的基础掌握的牢固程度,代码中的很多地方都是可以细细品味的. 为什么要写这么一个小东东呢,因为我生活在大河北,那雾霾醇厚的很 ...

随机推荐

  1. 零元学Expression Blend 4 - Chapter 28 ListBox的基本运用与更改预设样式

    原文:零元学Expression Blend 4 - Chapter 28 ListBox的基本运用与更改预设样式 本章将先教大家认识ListBox的基本运用与更改预设样式 本章将先教大家认识List ...

  2. 零元学Expression Blend 4 &ndash; Chapter 21 以实作案例学习MouseDragElementBehavior

    原文:零元学Expression Blend 4 – Chapter 21 以实作案例学习MouseDragElementBehavior 本章将教大家如何运用Blend 4内建的行为注入元件「Mou ...

  3. 零元学Expression Blend 4 - Chapter 4元件重复运用的观念

    原文:零元学Expression Blend 4 - Chapter 4元件重复运用的观念 本章将教大家Blend元件重复运用的观念,这在Silverlight设计中是非常重要的,另外加码赠送渐层工具 ...

  4. 企业级架构 MVVM 模式指南 (WPF 和 Silverlight 实现) 译(3)

    第一章 表现模式关注分离(soc)是企业及软件开发中非常有用的核心原则,也是许多表现模式背后的驱动力量.在WPF和Silverlight开发中,MVVM成为了实现关注分离最为有效的设计模式.然而,这种 ...

  5. AngularJS的简单使用(入门级)

    AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中. AngularJS有着诸多特性,最为 ...

  6. Qt编程中QDiaog的ESC建

    最近使用QDialog时,按了下Esc键,导致QDialog被关闭,而后续的数据处理出现了问题.原来在QDialog中按下Esc键会默认调用reject()方法而不是closeEvent(QClose ...

  7. Spring Type Conversion(Spring类型转换源码探究)

    1:概述 类型转换系统负责Spring框架中对象类型转换和格式化工作. ConversionService默认实现UML图如下所示: GenericConversionService(通用类型转换服务 ...

  8. 使用LinkedList模拟一个堆栈或者队列数据结构。

    堆栈:先进后出 First in last out filo 队列:先进先出 First in last out filo使用LinkedList的方法,addFirst addLast getFir ...

  9. CS代码代写, 程序代写, java代写, python代写, c/c++代写,csdaixie,daixie,作业代写,代写

    互联网一线工程师程序代写 微信联系 当天完成特色: 互联网一线工程师 24-48小时完成.用心代写/辅导/帮助客户CS作业. 客户反馈与评价 服务质量:保证honor code,代码原创.参考课程sl ...

  10. 11 CSS的三种引入方式和基本选择器

    <!-- 整体说明: 1.CSS的三种引入方式 (1)行内样式 (2)内接样式 (3)外接样式 2.CSS的基本选择器 (1)id选择器 (引用方式:#id) (2)标签选择器(引用方式:标签名 ...