![Python 3 爬虫、数据清洗与可视化实战(第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/935/32517935/b_32517935.jpg)
3.2 获取API数据
通过3.1节可以知道,API提供了全国3181个城市的天气预报,可以通过互联网在线爬取或读取城市列表,然后通过循环语句一次性获取3181个城市的天气预报。通过阅读文档读取API提供的城市,其城市数量是会变动的,因此最好的方式是直接从网上读取,这样就可以省去人工更新城市列表的工作了。
从网上读取数据的第一步是获取城市列表,然后根据城市列表循环,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_6.jpg?sign=1739271283-o7nflmfABVcSOOJSS2bedzIT18nloZYx-0-5d7719b46337aa28631d4d1aaa301c05)
运行上面这段代码可以提取所有的城市代码,如图3-6所示。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_7.jpg?sign=1739271283-aYt4gkjhF6b8rbCb2MVJFjArYYjTwn5W-0-5928b00f0e45a0c6f2b104c6ea007e77)
图3-6
上例通过requests.get()方法获取数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_8.jpg?sign=1739271283-hc6bBxg2NObvIfu09sqY7JNcoNPIeUZW-0-11a794301495ab0e3ced853dfe910428)
观察打印出来的数据,可以发现并不需要前6行,如图3-7所示。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_9.jpg?sign=1739271283-1rxiyqU2RTh5mUYdJ1knUcvpi82A0QUL-0-3a1af84c303259a49c2702470675b79d)
图3-7
接下来用split()方法将文本转换成列表,再通过一个循环将前6行内容删除。
然后将一大串文本分割出来,这里可以用换行符将每行文本分开。在Python中,\n表示换行符。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_10.jpg?sign=1739271283-mseyE91VYwJdyo85b1kSIavWpn7HFskR-0-a0f90a75665f67914b1e5052c91301cc)
删除数据使用的是remove()方法,并且每次都删除第一行(序号为0)数据。因为每次删除第一行数据,所以第二行数据都会变成下一次执行的第一行数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_11.jpg?sign=1739271283-y8I3p5IML4nsaGzlBX83ba9oNGCNv91c-0-c6b8e073c03be418c3f64c4c0a8a6a59)
通过前面的接口信息可以知道,只要获取城市/地区编码就可以了。这里从便捷的角度出发,提取每行的第3~14个字符(由于Python数组是从0开始计数的,因此用2:13表示),共计12个字符,然后通过一个列表元素循环将城市/地区编码打印出来。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_12.jpg?sign=1739271283-PhjoNzFwuS3cigJtXaB7ZpeD7gNTCV71-0-d49c954169115e8685ea8763e7326634)
完成城市/地区编码的提取后,下一步就是调用接口获取数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_13.jpg?sign=1739271283-QwKWEQpkarHEwg0qvAbhmMpGCUKRiVdA-0-614c9eaa71be5805bfa7c7dce13af011)
数据是以JSON的格式返回的,每个城市/地区都是一个JSON,如图3-8所示。
这段代码调用了time库,这是为了使用sleep()(睡眠)函数,也就是延时函数。因为API提供了3181个城市/地区的天气预报,这个循环就要执行3181次。为了避免访问服务器过于频繁,保证爬虫的稳定性,这里让程序每次访问后等待1秒钟。在写爬虫的时候不管需要访问的次数是多还是少,最好养成写延时的习惯,延时函数代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_14.jpg?sign=1739271283-UewuolrFUeUa9PDwzVdVBUGB9sSaTMHH-0-671ea614b126b79ef798ce35581de558)
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_15.jpg?sign=1739271283-oQMVn9SZ81BzVH4UOhsOhx9lYDLLnVQk-0-13dc1840d7bd85bbc14b72ec550533ea)
图3-8
如果要将返回的JSON数据解析出来,则可以使用for循环语句。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_16.jpg?sign=1739271283-hjbzdjaANMbZwXR7INElnwkcfRa326oZ-0-5114df0cd2794aa1ca82804fce8bedf9)
代码执行结果如图3-9所示。
接下来使用JSON在线结构化的工具观察数据结构。
将其中一个城市的返回数据复制并粘贴到左侧的文本框中,然后单击中间的右三角按钮,就会得到如图3-10所示的结果。通过观察路径可知,3天的天气预报数据在[daily_forecast]路径下,由[0]、[1]和[2]这3个数据节点分别存放3天的天气预报数据,而每天的最高温度在[daily_forecast][n][tmp][max]路径下,其中[n]表示分节点[0]、[1]、[2]。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_17.jpg?sign=1739271283-SU7BbBmnmt7VnpFwm1MDGFxhE7uM6WTy-0-e91c3a30e4c1b0eece9d4bb12f103d5f)
图3-9
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_18.jpg?sign=1739271283-BRubtfr3dZmmRTbTwqZbbQ2yJr6Jdvy8-0-ad49034df255e5a6d0571ec0a1cbe9b1)
图3-10
如果JSON工具报错,则需要检查复制的内容是否存在多了空格或者少了符号之类的问题,这些都是新手常犯的错误。
requests库返回的数据可以编码成JSON格式的数据,只有JSON对象才适用上面分析的路径,表现方式如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_19.jpg?sign=1739271283-XwLDya2hd4scrhZpGUnAT5hsGsTN4Xdg-0-7b9d4044cc45ce3265749650df9b3a12)