这段代码实例,见证了数万人入门编程
另一个是“查天气”。这个例子算得上一个简单的“网络爬虫”,是你的代码从单机向网络进化的第一步,并且涉及到文件读写、类型转换、多层循环、模块等功能的综合应用。因此,当你能独立完成这样一个案例时(包括城市代码的抓取),可以说是完成了 Python 编程的“入门”。
很多同学学到这里都会遇到一些阻碍,加上接口的变动和版本的更新,我经常会收到各种提问。今天在这儿,我做一个相对完整的解说,并且附上包含不同版本、不同方式、不同接口的更新版示例代码。
回复 查天气 查看对应教程及代码
1. 请求地址
教程原版接口,获取某一城市的天气:
http://www.weather.com.cn/data/cityinfo/101010100.html
此接口需要城市代码。地址目前依然有效,但结果并不更新,只可用作代码练习,无实用价值。
浏览器中可能会是乱码,但代码中可以正常处理。
更好的替换接口:
http://wthrcdn.etouch.cn/weather_mini?citykey=101010100
此接口需要城市代码,返回 JSON 格式的昨日天气及5天内的天气预报,包括气温、指数、空气质量、风力等。信息丰富且准确,推荐使用。
此接口还可以通过直接提供城市名称来查询
http://wthrcdn.etouch.cn/weather_mini?city=北京
需要注意的是,对方服务器会按照 UTF-8 编码来处理 city 参数,所以在 windows 下直接这样请求可能会失败。
2. 城市列表
上述接口中提及的城市列表,有几种获取方式:
直接下载文件
回复 查天气 可见地址
查询城市代码
https://blog.csdn.net/hello_haozi/article/details/7564223
此页面上有给出城市代码,你可以复制下来通过程序整理。
通过接口抓取
http://m.weather.com.cn/data3/city.xml
具体方法见【课程 查天气-4】
抓取城市代码的难度要比查询天气本身难度更高。
3. 网络模块
urllib2
教程最初给的方法是基于 Python2 内置的 urllib2 模块,无需安装其他库。
urllib
在 Python3,urllib2 模块被替代,需使用 urllib.request 模块。
requests
这是一个外部的网络模块,需安装。之前文章有介绍过:这个男人让你的爬虫开发效率提升8倍。使用它,会让开发简便许多,少踩很多坑。即使你用原生网络模块完成了代码,也强烈建议体验下 requests。
4. 中文编码
编码一向是 Python 的大坑,这个例子里也不例外。可能出问题的主要有3个地方:
city.py
由于代码中有中文,所以必须在文件第一行声明编码。又因为我们需要从控制台获取输入,所以这两者的编码必须一致,否则就查不到城市编码。
windows 上如果出现查不到编码的情况,尝试都设置成 gbk,而且建议在 IDE 里新建文件,把内容复制进去,而不是直接使用下载的 city.py。或者使用 PyCharm,按 PyCharm 快速上手指南 这里介绍的方法,全部设成 UTF-8 编码。
拿到的返回结果
返回值里的中文是 UTF-8 编码,requests 需要手动设定。另外,Python2 直接输出 dict 是不会解码的,需要对每个值单独输出。
发送的url
前面提到,有个接口可以直接将城市名作为参数。如果你是 windows,需要使用 quote 方法将字符转成 UTF-8 的 URL 编码后再发送请求。
5. 其他问题
gzip
有些接口的结果进行了 gzip 压缩,导致拿到的返回值是一段完全看不懂的乱码,需通过 gzip 解压缩。requests 不存在这个问题,urllib 的处理参见代码。
调试
开发中总会遇到各种问题,遇到问题不要抓瞎,要去调试:
1. 多加 print 输出。了解程序的运行状态和变量的值,看看和预期是否一致。
2. 注意看报错信息,出在哪一行,是什么错。
3. 一行代码做一件事。如果报错的代码行连续调用了几个函数,把它分成几行代码再运行。
4. 在出错行之前输出信息,查看此行代码使用到的变量都是什么值什么类型。
5. 开发时先不要加异常处理,否则你无法看到报错信息