技术心得:如何用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

相关文章
|
1天前
|
JSON 安全 API
如何高效编写API接口:以Python与Flask为例
构建RESTful API的简明教程:使用Python的Flask框架,从环境准备(安装Python,设置虚拟环境,安装Flask)到编写首个API(包括获取用户列表和单个用户信息的路由)。运行API服务器并测试在`http://127.0.0.1:5000/users`。进阶话题包括安全、数据库集成、API文档生成和性能优化。【6月更文挑战第27天】
17 7
|
1天前
|
数据采集 JSON 数据可视化
【Python实战】Python对中国500强排行榜数据进行可视化分析
【Python实战】Python对中国500强排行榜数据进行可视化分析
|
2天前
|
存储 人工智能 运维
超大规模云网络技术新突破!阿里云斩获中国自动化学会科技进步一等奖
阿里云携手浙江大学、上海交大联合攻坚的超大规模云网络技术及应用成果,斩获中国自动化学会(CAA)科技进步奖一等奖。该成果实现了超大规模云网络调控技术的高性能突破,将十万级任务配置下发提升至秒级的超高水平,填补了该项技术的国内空白。
|
2天前
程序技术好文:计算机网络(九)——STP原理
程序技术好文:计算机网络(九)——STP原理
|
1天前
|
存储 安全 网络安全
云计算与网络安全:技术融合与信息保障
随着信息技术的快速发展,云计算作为一种革命性的计算模式已经深入各行各业。然而,云计算的普及也带来了网络安全的挑战,如何在信息共享和隐私保护之间找到平衡成为了云计算发展的关键问题。本文探讨了云服务的技术特点、网络安全的挑战及其解决方案,以及信息安全在这一背景下的重要性和实施策略。
9 0
|
1天前
|
数据采集 XML 存储
【Python实战】Python采集二手车数据——超详细讲解
【Python实战】Python采集二手车数据——超详细讲解
|
1天前
|
JSON 安全 API
实战指南:使用PHP构建高性能API接口服务端
构建RESTful API的简要指南:使用PHP和Laravel,先安装Laravel并配置数据库,接着在`api.php`中定义资源路由,创建`PostController`处理CRUD操作,定义`Post`模型与数据库交互。使用Postman测试API功能,如创建文章。别忘了关注安全性、错误处理和性能优化。
12 2
|
3天前
|
人工智能 运维 Serverless
函数计算产品使用问题之启动的实例是否有调用api接口停止功能
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
4天前
|
数据挖掘 API 开发者
​Email API有哪些,最好的3个API接口有哪些
Email API如SendGrid、Mailgun和AOKSend是企业自动化邮件通信的关键工具。它们提供邮件发送、接收和管理功能,提升效率,优化客户体验。SendGrid以其高可靠性、强大分析和易于集成备受青睐;Mailgun以灵活性和高发送率著称;而AOKSend则以其高效、详细分析和易用性脱颖而出。通过使用这些API,企业能实现定制化邮件服务,跟踪性能,提升邮件营销效果。

热门文章

最新文章