技术心得:如何用Python和API收集与分析网络数据?

简介: 技术心得:如何用Python和API收集与分析网络数据?

摘自


本文以一款阿里云市场历史天气查询产品为例,为你逐步介绍如何用 Python 调用 API 收集、分析与可视化数据。希望你举一反三,轻松应对今后的 API 数据收集与分析任务。


市场


我们尝试的,是他们找到的阿里云市场的一款 API 产品,提供天气数据。


它来自于易源数据,链接在


这是一款收费 API ,100次调用的价格为1分钱。


作为作业练习,100次调用已经足够了。


这价格,他们表示可以接受。


我自己走了一遍流程。


点击“立即购买”按钮。


你会被引领到付费页面。如果你没有登录,可以根据提示用淘宝账号登录。


支付1分钱以后,你会看到如下的成功提示。


之后,系统会提示给你一些非常重要的信息。


注意上图中标红的字段。


这是你的AppCode,是后面你调用 API 接口获取数据,最为重要的身份认证手段,请点击“复制”按钮把它存储下来。


点击上图中的商品名称链接,回到产品介绍的页面。


这个产品的 API 接口,提供多种数据获取功能。


学生们尝试利用的,是其中“利用id或地名查询历史天气”一项。


请注意这张图里,有几样重要信息:


调用地址:这是我们访问 API 的基本信息。就好像你要去见朋友,总得知道见面的地址在哪里;


请求方式:本例中的 GET ,是利用 HTTP 协议请求传递数据的主要形式之一;


请求参数:这里你要提供两个信息给 API 接口,一是“地区名称”或者“地区id”(二选一),二是月份数据。需注意格式和可供选择的时间范围。


我们往下翻页,会看到请求示例。


默认的请求示例,是最简单的 curl 。


如果你的操作系统里面已经安装了 curl (没有安装的话,可以点击这个链接,寻找对应的操作系统版本下载安装),尝试把上图中 curl 开头的那一行代码拷贝下来,复制到文本编辑器里面。


就像这样:


curl -i -k --get --include '' -H 'Authorization:APPCODE 你自己的AppCode'


然后,一定要把其中的“你自己的AppCode”这个字符串,替换为你真实的 AppCode 。


把替换好的语句复制粘贴到终端窗口里面运行。


运行结果,如下图所示:


看见窗口下方包含中文的数据了吗?


利用 API 获取数据,就是这么简单。


既然终端执行一条命令就可以,那我们干嘛还要编程呢?


好问题!


因为我们需要的数据,可能不是一次调用就能全部获得。


你需要重复多次调用 API ,而且还得不断变化参数,积累获得数据。


每次若是都这样手动执行命令,效率就太低了。


API 的提供方,会为用户提供详细的文档与说明,甚至还包括样例。


上图中,除了刚才我们使用的 curl ,还包括以下语言访问 API 接口的样例说明:


Java


C#


PHP


Python


Object C


我们以 Python 作为例子,点开标签页看看。


你只需要把样例代码全部拷贝下来,用文本编辑器保存为“.py”为扩展名的 Python 脚本文件,例如 demo.py 。


再次提醒,别忘了,把其中“你自己的AppCode”这个字符串,替换为你真实的 AppCode,然后保存。


在终端下,执行:


python demo.py


如果你用的是 2.7 版本的 Python ,就立即可以正确获得结果了。


为什么许多学生做不出来结果呢?


我让他们实际跑了一下,发现确实有的学生粗心大意,忘了替换自己的 AppCode 。


但是大部分同学,由于安装最新版本的 Anaconda (Python 3.6版),都遇到了下面的问题:


你可能会认为这是因为没有正确安装 urllib2 模块,于是执行


pip install urllib2


你可能会看到下面的报错提示:


你也许尝试去掉版本号,只安装 urllib,即:


pip install urllib


但是结果依然不美妙:


有些 Python 开发者看到这里,可能会嘲笑我们:Python 3版本里面,urllib 被拆分了啊!地球人都知道,你应该……


请保持一颗同理心。


想想一个普通用户,凭什么要了解不同版本 Python 之间的语句差异?凭什么要对这种版本转换的解决方式心里有数?


在他们看来,官方网站提供的样例,就应该是可以运行的。报了错,又不能通过自己的软件包安装“三板斧”来解决,就会慌乱和焦虑。


更进一步,他们也不太了解 JSON 格式。


虽然,JSON已是一种非常清晰的、人机皆可通读的数据存储方式了。


他们想了解的,是怎么把问题迁移到自己能够解决的范围内。


例如说,能否把 JSON 转换成 Excel 形式的数据框?


如果可以,他们就可以调用熟悉的 Excel 命令,来进行数据筛选、分析与绘图了。


他们还会想,假如 Python 本身,能一站式完成数据读取、整理、分析和可视化全流程,那自然更好。


但是,样例,样例在哪里呢?


在我《Python编程遇问题,文科生怎么办?》一文中,我曾经提到过,这种样例,对于普通用户的重要性。


没有“葫芦”,他们又如何“照葫芦画瓢”呢?


既然这个例子中,官方文档没有提供如此详细的代码和讲解样例,那我就来为你绘制个“葫芦”吧。


下面,我给你逐步展示,如何在 Python 3 下,调用该 API 接口,读取、分析数据,和绘制图形。


环境


首先我们来看看代码运行环境。


前面提到过,如果样例代码的运行环境,和你本地的运行环境不一,计时代码本身没问题,也无法正常执行。


所以,我为你构建一个云端代码运行环境。(如果你对这个代码运行环境的构建过程感兴趣,欢迎阅读我的《如何用iPad运行Python代码?》一文。)


请点击这个链接(直接进入咱们的实验环境。


你不需要在本地计算机安装任何软件包。只要有一个现代化浏览器(包括Google Chrome, Firefox, Safari和Microsoft Edge等)就可以了。全部的依赖软件,我都已经为你准备好了。


打开链接之后,你会看见这个页面。


这个界面来自 Jupyter Lab。


图中左侧分栏,是工作目录下的全部文件。


右侧打开的,是咱们要使用的ipynb文件。


根据我的讲解,请你逐条执行,并仔细观察运行结果。


本例中,我们主要会用到以下两个新的软件包。


首先是号称“给人用”(for humans)的HTTP工具包requests。


这款工具,不仅符合人类的认知与使用习惯,而且对 Python 3 更加友好。作者 Kenneth Reitz 甚至在敦促所有的 Python 2 用户,赶紧转移到 Python 3 版本。


The use of Python 3 is highly preferred over Python 2. Consider upgrading your applications and infrastructure if you find yourself still using Python 2 in production today. If you are using Python 3, congratulations — you are indeed a person of excellent taste. —Kenneth Reitz


我们将用到的一款绘图工具,叫做 plotnine 。


它实际上本不是 Python 平台上的绘图工具,而是从 R 平台的 ggplot2 移植过来的。


要知道,此时 Python 平台上,已经有了 matplotlib, seaborn, bokeh, plotly 等一系列优秀的绘图软件包。


那为什么还要费时费力地,移植 ggplot2 过来呢?


因为 ggplot2 的作者,是大名鼎鼎的 R 语言大师级人物 Hadley Wickham 。


他创造 ggplot2,并非为 R 提供另一种绘图工具,而是提供另一种绘图方式。


ggplot2 完全遵守并且实现了 Leland Wilkinson 提出的“绘图语法”(Grammar of Graphics),图像的绘制,从原本的部件拆分,变成了层级拆分。


这样一来,数据可视化变得前所未有地简单易学,且功能强大。


我会在后文的“代码”部分,用详细的叙述,为你展示如何使用这两个软件包。


我建议你先完全按照教程跑一遍,运行出结果。


如果一切正常,再将其中的数据,替换为你自己感兴趣的内容。


之后,尝试打开一个空白 ipynb 文件,根据教程和文档,自己敲代码,并且尝试做调整。


这样会有助于你理解工作流程和工具使用方法。


下面我们来看代码。


代码


首先,读入HTTP工具包requests。


import requests


第二句里面,有“Your AppCode here”字样,请把它替换为你自己的AppCode,否则下面运行会报错。


appcode = 'Your AppCode here'


我们尝试获取丽江5月份的天气信息。


在API信息页面上,有城市和代码对应的表格。


位置比较隐蔽,在公司简介的上方。


我把这个 Excel 文档的网址放在了这里(你可以直接点击下载。


下载该 Excel 文件后打开,根据表格查询,我们知道“101291401”是丽江的城市代码。


我们将其写入areaid变量。


日期我们选择本文写作的月份,即2018年5月。


areaid = "101291401"


month = "201805"


下面我们就设置一下 API 接口调用相关的信息。


根据API信息页面上的提示,我们的要访问的网址为:需要输入的两个参数,就是刚才已经设置的areaid和month。


另外,我们需要验证身份,证明自己已经付费了。


点击上图中蓝色的“API 简单身份认证调用方法(APPCODE)”,你会看到以下示例页面。


看来我们需要在HTTP数据头(header)中,加入 AppCode。


我们依次把这些信息都写好。


url = ''


payload = {'areaid': areaid, 'month': month}


headers = {'Authorization': 'APPCODE {}'.format(appcode)}


下面,我们就该用 requests 包来工作了。


requests 的语法非常简洁,只需要指定4样内容:


调用方法为“GET”


访问地址 url


url中需要附带的参数,即 payload (包含 areaid和month的取值)


HTTP数据头(header)信息,即 AppCode


r = requests.get(url, params=payload, headers=headers)


执行后,好像……什么也没有发生啊!


我们来查看一下:


r


Python 告诉我们:


[span class="hljs-name">Response 【200】>


返回码“200”的含义为访问成功。


回顾一下,《如何用R和API免费获取Web数据?》一文中,我们提到过:


以2开头的状态编码是最好的结果,意味着一切顺利;如果状态值的开头是数字4或者5,那就有问题了,你需要排查错误。


既然调用成功,我们看看 API 接口返回的具体数据内容吧。


调用返回值的 content 属性:


r.content


这一屏幕,密密麻麻的。


其中许多字符,甚至都不能正常显示。这可怎么好?


没关系,从 API 信息页上,我们得知返回的数据,是 JSON 格式。


那就好办了,我们调用 Python 自带的 json 包。


import json


用 json 包的字符串处理功能(loads)解析返回内容,结果存入 content_json。


content_json = json.loads(r.content)


看看 content_json 结果:


content_json


可以看到,返回的信息很完整。而且刚刚无法正常显示的中文,此时也都显现了庐山真面目。


下一步很关键。


我们把真正关心的数据提取出来。


//代码效果参考:http://hnjlyzjd.com/hw/wz_24876.html

我们不需要返回结果中的错误码等内容。

我们要的,是包含每一天天气信息的列表。


观察发现,这一部分的数据,存储在 'list' 中,而 'list' ,又存储在 'showapi_res_body' 里面


所以,为选定列表,我们需要指定其中的路径:


content_json【'showapi_res_body'】【'list'】


冗余信息都被去掉了,只剩下我们想要的列表。


但是对着一个列表操作,不够方便与灵活。


我们希望将列表转换为数据框。这样分析和可视化就简单多了。


大不了,我们还可以把数据框直接导出为 Excel 文件,扔到熟悉的 Excel 环境里面,去绘制图形。


读入 Python 数据框工具 pandas 。


import pandas as pd


我们让 Pandas 将刚刚保留下来的列表,转换为数据框,存入 df 。


df = pd.DataFrame(content_json【'showapi_res_body'】【'list'】)


看看内容:


df


此时,数据显示格式非常工整,各项信息一目了然。


写到这里,你基本上搞懂了,如何读取某个城市、某个月份的数据,并且整理到 Pandas 数据框中。


但是,我们要做分析,显然不能局限在单一月份与单一城市。


每次加入一组数据,如果都得从头这样做一遍,会很辛苦。而且语句多了,执行起来,难免顾此失彼,出现错误。


//代码效果参考:http://hnjlyzjd.com/xl/wz_24874.html

所以,我们需要把刚刚的代码语句整合起来,将其模块化,形成函数。

这样,我们只需要在调用函数的时候,传入不同的参数,例如不同的城市名、月份等信息,就能获得想要的结果了。


综合上述语句,我们定义一个传入城市和月份信息,获得数据框的完整函数。


def get_df(areaid, areaname_dict, month, appcode):


url = ''


payload = {'areaid': areaid, 'month': month}


headers = {'Authorization': 'APPCODE {}'.format(appcode)}


r = requests.get(url, params=payload, headers=headers)


content_json = json.loads(r.content)


df = pd.DataFrame(content_json【'showapi_res_body'】【'list'】)


df【'areaname'】 = areaname_dict【areaid】


return df


注意除了刚才用到的语句外,我们为函数增加了一个输入参数,即areaname_dict。


它是一个字典,每一项分别包括城市代码,和对应的城市名称。


根据我们输入的城市代码,函数就可以自动在结果数据框中添加一个列,注明对应的是哪个城市。


当我们获取多个城市的数据时,某一行的数据说的是哪个城市,就可以一目了然。


反之,如果只给你看城市代码,你很快就会眼花缭乱,不知所云了。


但是,只有上面这一个函数,还是不够高效。


毕竟我们可能需要查询若干月、若干城市的信息。如果每次都调用上面的函数,也够累的。


所以,我们下面再编写一个函数,帮我们自动处理这些脏活儿累活儿。


def get_dfs(areaname_dict, months, appcode):


dfs = 【】


for areaid in areaname_dict:


dfs_times = 【】


for month in months:


temp_df = get_df(areaid, areaname_dict, month, appcode)


dfs_times.append(temp_df)


area_df = pd.concat(dfs_times)


dfs.append(area_df)


return dfs


说明一下,这个函数接受的输入,包括城市代码-名称字典、一系列的月份,以及我们的 AppCode。


它的处理方式,很简单,就是个双重循环。


外层循环负责遍历所有要求查询的城市,内层循环遍历全部指定的时间范围。


它返回的内容,是一个列表。


列表中的每一项,都分别是某个城市一段时间(可能包含若干个月)的天气信息数据框。


我们先用单一城市、单一月份来试试看。


还是2018年5月的丽江。


areaname_dict = {"101291401":"丽江"}


months = 【"201805"】


我们将上述信息,传入 get_dfs 函数。


dfs = get_dfs(areaname_dict, months, appcode)


看看结果:


dfs


返回的是一个列表。


因为列表里面只有一个城市,所以我们只让它返回第一项即可。


dfs【0】


这次显示的,就是数据框了:


测试通过,下面我们趁热打铁,把天津、上海、丽江2018年初至今所有数据都读取出来。


先设定城市:


areaname_dict = {"101030100":"天津", "101020100":"上海", "101291401":"丽江"}


再设定时间范围:


months = 【"201801", "201802", "201803", "201804", "201805"】


咱们再次执行 get_dfs 函数。


dfs = get_dfs(areaname_dict, months, appcode)


看看这次的结果:


dfs


结果还是一个列表。


列表中的每一项,对应某个城市2018年年初到5月份本文写作时,这一段时间范围天气数据。


假设我们要综合分析几个城市的天气信息,那么就可以把这几个数据框整合在一起。


用到的方法,是 Pandas 内置的 concat 函数。


它接收一个数据框列表,把其中每一个个数据框沿着纵轴(默认)连接在一起。


df = pd.concat(dfs)


看看此时的总数据框效果:


df


这是开头部分:


这是结尾部分:


3个城市,4个多月的数据都正确读取和整合了。


下面我们尝试做分析。


首先,我们得搞清楚数据框中的每一项,都是什么格式:


df.dtypes


aqi object


aqiInfo object


aqiLevel object


max_temperature object


min_temperature object


time object


weather object


wind_direction object


wind_power object


areaname object


dtype: object


所有的列,全都是按照 object 处理的。


什么叫 object ?


在这个语境里,你可以将它理解为字符串类型。


但是,咱们不能把它们都当成字符串来处理啊。


例如日期,应该按照日期类型来看待,否则怎么做时间序列可视化?


AQI的取值,如果看作字符串,那怎么比较大小呢?


所以我们需要转换一下数据类型。


先转换日期列:


df.time = pd.to_datetime(df.time)


再转换 AQI 数值列:


df.aqi = pd.to_numeric(df.aqi)


看看此时 df 的数据类型:


df.dtypes


aqi int64


aqiInfo object


aqiLevel object


max_temperature object


min_temperature object


time datetime64【ns】


weather object


wind_direction object


wind_power object


areaname object


dtype: object


这次就对了,日期和 AQI 都分别变成了我们需要的类型。其他数据,暂时保持原样。


有的是因为本来就该是字符串,例如城市名称。


另一些,是因为我们暂时不会用到。


下面我们绘制一个简单的时间序列对比图形。


读入绘图工具包 plotnine 。


注意我们同时读入了 date_breaks,用来指定图形绘制时,时间标注的间隔。


import matplotlib.pyplot as plt


%matplotlib inline


from plotnine import *


from mizani.breaks import date_breaks


正式绘图:


(ggplot(df, aes(x='time', y='aqi', color='factor(areaname)')) + geom_line() +


scale_x_datetime(breaks=d

相关文章
|
2天前
|
SQL 并行计算 API
Dask是一个用于并行计算的Python库,它提供了类似于Pandas和NumPy的API,但能够在大型数据集上进行并行计算。
Dask是一个用于并行计算的Python库,它提供了类似于Pandas和NumPy的API,但能够在大型数据集上进行并行计算。
19 9
|
2天前
|
机器学习/深度学习 PyTorch 算法框架/工具
图神经网络是一类用于处理图结构数据的神经网络。与传统的深度学习模型(如卷积神经网络CNN和循环神经网络RNN)不同,
图神经网络是一类用于处理图结构数据的神经网络。与传统的深度学习模型(如卷积神经网络CNN和循环神经网络RNN)不同,
15 9
|
2天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
【7月更文挑战第13天】在Web开发中,AJAX和Fetch API是实现页面无刷新数据交换的关键。在Flask博客系统中,通过创建获取评论的GET路由,我们可以展示使用AJAX和Fetch API的前端实现。AJAX通过XMLHttpRequest发送请求,处理响应并在成功时更新DOM。Fetch API则使用Promise简化异步操作,代码更现代。这两个工具都能实现不刷新页面查看评论,Fetch API的语法更简洁,错误处理更直观。掌握这些技巧能提升Python Web项目的用户体验和开发效率。
15 7
|
2天前
|
XML 前端开发 API
惊艳全场的秘诀!AJAX、Fetch API与Python后端,打造令人惊叹的Web应用!
【7月更文挑战第13天】构建现代Web应用的关键在于提供无缝用户体验,这涉及AJAX和Fetch API的异步数据交换以及Python(如Flask)的后端支持。Fetch API以其基于Promise的简洁接口,改进了AJAX的复杂性。例如,一个Flask应用可提供用户数据,前端利用Fetch API在不刷新页面的情况下显示信息。这种结合提升了效率,减少了服务器负载,是现代Web开发的趋势。随着技术发展,预期将有更多工具优化这一过程。
11 3
|
2天前
|
自然语言处理 程序员 编译器
`pylatex`是一个Python库,用于生成LaTeX文档。LaTeX是一种用于高质量排版和打印的文档准备系统,特别适用于科学、技术和数学文档。
`pylatex`是一个Python库,用于生成LaTeX文档。LaTeX是一种用于高质量排版和打印的文档准备系统,特别适用于科学、技术和数学文档。
11 2
|
1天前
|
前端开发 API 开发者
深度剖析:AJAX、Fetch API如何成为Python后端开发者的最佳拍档!
【7月更文挑战第14天】在Web开发中,前端与后端的协作关键在于异步数据交换。AJAX和Fetch API是两种主要技术,用于不刷新页面的情况下与服务器通信。AJAX依赖XMLHttpRequest,常用于JSON数据传输,而Fetch API是现代替代品,基于Promise,语法简洁。Python的Flask框架可创建API接口来响应这些请求。了解并熟练使用这些技术能提升Python后端开发的效率,构建高性能的Web应用。
6 0
|
1天前
|
前端开发 API 开发者
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
【7月更文挑战第14天】在Web开发中,AJAX和Fetch API扮演着关键角色,用于前后端异步通信。AJAX通过XMLHttpRequest实现页面局部更新,但回调模式和复杂API有一定局限。Fetch API作为现代替代,利用Promise简化异步处理,提供更丰富功能和错误处理。Python后端如Flask、Django支持这些交互,助力构建高性能应用。从AJAX到Fetch API的进步,结合Python,提升了开发效率和用户体验。
6 0
|
1天前
|
XML 前端开发 API
颠覆传统!AJAX、Fetch API与Python后端,开启Web开发新篇章!
【7月更文挑战第14天】Web开发中,AJAX作为异步通信先驱,与新兴的Fetch API一起革新交互体验。Fetch基于Promise,简化了请求处理。Python后端,如Flask,提供稳定支撑。这三者的融合,推动Web应用达到新高度,实现高效、实时交互。通过示例展示,我们看到从发送请求到更新UI的流畅过程,以及Python如何轻松返回JSON数据。这种组合揭示了现代Web开发的潜力和魅力。
8 0
|
1天前
|
前端开发 JavaScript API
告别‘老司机’时代,AJAX与Fetch API让你的前端与Python后端无缝对接!
【7月更文挑战第14天】前端与后端交互的关键技术是AJAX和Fetch API。AJAX允许不刷新页面更新内容,而Fetch API提供了Promise基
|
2天前
|
数据可视化 Python
时间序列分析是一种统计方法,用于分析随时间变化的数据序列。在金融、经济学、气象学等领域,时间序列分析被广泛用于预测未来趋势、检测异常值、理解周期性模式等。在Python中,`statsmodels`模块是一个强大的工具,用于执行各种时间序列分析任务。
时间序列分析是一种统计方法,用于分析随时间变化的数据序列。在金融、经济学、气象学等领域,时间序列分析被广泛用于预测未来趋势、检测异常值、理解周期性模式等。在Python中,`statsmodels`模块是一个强大的工具,用于执行各种时间序列分析任务。
7 0