![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=1739335383-4TXNu2TPWclgK7WU72NKjuhdfdGVFi1c-0-65d23e75fac241da69a4ed626c229a98)
运行上面这段代码可以提取所有的城市代码,如图3-6所示。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_7.jpg?sign=1739335383-T4NK0jV180CssSlNXjXceIMxSjy8VKbL-0-931e9aac000170dad0efa3c07e216f22)
图3-6
上例通过requests.get()方法获取数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_8.jpg?sign=1739335383-zKMtCLQOIEE0VCJ4TKwGWobdwRJjGepU-0-5d5b02d014633b66f7b2f7bb4fe0a45b)
观察打印出来的数据,可以发现并不需要前6行,如图3-7所示。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_9.jpg?sign=1739335383-RJZMl8r4yk7fmnklI5MAs5zmohHPDtdC-0-28c0f299e44a89dab2053f67d0b1fc62)
图3-7
接下来用split()方法将文本转换成列表,再通过一个循环将前6行内容删除。
然后将一大串文本分割出来,这里可以用换行符将每行文本分开。在Python中,\n表示换行符。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_10.jpg?sign=1739335383-rjdrWeyggHNi8nZzVKEXdMgt9jF39EUM-0-b636b03e8943ffcf45e907d6ddb900da)
删除数据使用的是remove()方法,并且每次都删除第一行(序号为0)数据。因为每次删除第一行数据,所以第二行数据都会变成下一次执行的第一行数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_11.jpg?sign=1739335383-BS7tvAEdGHYRtotSNFBzb7jkEeQN9Bej-0-e12e394ef073b53029c6ae7f336d17a4)
通过前面的接口信息可以知道,只要获取城市/地区编码就可以了。这里从便捷的角度出发,提取每行的第3~14个字符(由于Python数组是从0开始计数的,因此用2:13表示),共计12个字符,然后通过一个列表元素循环将城市/地区编码打印出来。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_12.jpg?sign=1739335383-3VxoruPQdr1HO08rNsth1iKzMivlGF9p-0-41ca31323f9286ae3d37b8aa008b6f0c)
完成城市/地区编码的提取后,下一步就是调用接口获取数据,代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_13.jpg?sign=1739335383-z7s22M6mK1OtGWVNRSBIjAb1E6xSxsK7-0-6b948a8396859ba2b0254c4807af0b77)
数据是以JSON的格式返回的,每个城市/地区都是一个JSON,如图3-8所示。
这段代码调用了time库,这是为了使用sleep()(睡眠)函数,也就是延时函数。因为API提供了3181个城市/地区的天气预报,这个循环就要执行3181次。为了避免访问服务器过于频繁,保证爬虫的稳定性,这里让程序每次访问后等待1秒钟。在写爬虫的时候不管需要访问的次数是多还是少,最好养成写延时的习惯,延时函数代码如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_14.jpg?sign=1739335383-Vt8YhPsDJpEPSSVS6bIsqM7Lj1bKKKBr-0-6b252041c0865bf500002f4a8cc93a8b)
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_15.jpg?sign=1739335383-9Z9wiqgok8W6HoDN6XNyYMvh2HP83Yea-0-d0758e0411b2745f878f325458508383)
图3-8
如果要将返回的JSON数据解析出来,则可以使用for循环语句。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_16.jpg?sign=1739335383-hlr7V9lp08hPgyR3wQmPtpSJ98sFe88i-0-c7b44d0b39c283f316511747c83f33d3)
代码执行结果如图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=1739335383-28tNzWpLb0L3hkbWrseHnSF988uctMmg-0-19be87e2a6d04e95670653df04fb1088)
图3-9
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_18.jpg?sign=1739335383-z7LC5IL67Smdq5Vq9anV7qjrRGOxFLGC-0-71a79b0a0dd65319077d891c876f6cdb)
图3-10
如果JSON工具报错,则需要检查复制的内容是否存在多了空格或者少了符号之类的问题,这些都是新手常犯的错误。
requests库返回的数据可以编码成JSON格式的数据,只有JSON对象才适用上面分析的路径,表现方式如下。
![img](https://epubservercos.yuewen.com/3DAE1E/17545851106441906/epubprivate/OEBPS/Images/txt003_19.jpg?sign=1739335383-D5QDv1NCGg7Gip2dZh71S8enIVROLzr7-0-ce5c158410a79cfd5d5801aa37fcd6c5)