设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 109093|回复: 111
打印 上一主题 下一主题

【Python 第45课】 查天气(3)

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2013-7-24 16:47:29 |只看该作者 |正序浏览
python 查天气系列:
【Python 第43课】 查天气(1) http://bbs.crossincode.com/forum.php?mod=viewthread&tid=8
【Python 第44课】 查天气(2) http://bbs.crossincode.com/forum.php?mod=viewthread&tid=9
【Python 第45课】 查天气(3) http://bbs.crossincode.com/forum.php?mod=viewthread&tid=12
【Python 第46课】 查天气(4) http://bbs.crossincode.com/forum.php?mod=viewthread&tid=42

看一下我们已经拿到的json格式的天气数据:
  1. {
  2.     "weatherinfo": {
  3.         "city": "南京",
  4.         "cityid": "101190101",
  5.         "temp1": "37℃",
  6.         "temp2": "28℃",
  7.         "weather": "多云",
  8.         "img1": "d1.gif",
  9.         "img2": "n1.gif",
  10.         "ptime": "11:00"
  11.     }
  12. }
复制代码
直接在命令行中看到的应该是没有换行和空格的一长串字符,这里我把格式整理了一下。可以看出,它像是一个字典的结构,但是有两层。最外层只有一个key--“weatherinfo”,它的value是另一个字典,里面包含了好几项天气信息,现在我们最关心的就是其中的temp1,temp2和weather。

虽然看上去像字典,但它对于程序来说,仍然是一个字符串,只不过是一个满足json格式的字符串。我们用python中提供的另一个模块json提供的loads方法,把它转成一个真正的字典。
  1. import json

  2. data = json.loads(content)
复制代码
这时候的data已经是一个字典,尽管在控制台中输出它,看上去和content没什么区别,只是编码上有些不同:
  1. {u'weatherinfo': {u'city': u'\u5357\u4eac', u'ptime': u'11:00', u'cityid': u'101190101', u'temp2': u'28\u2103', u'temp1': u'37\u2103', u'weather': u'\u591a\u4e91', u'img2': u'n1.gif', u'img1': u'd1.gif'}}
复制代码
但如果你用type方法看一下它们的类型:
  1. print type(content)
  2. print type(data)
复制代码
就知道区别在哪里了。

之后的事情就比较容易了。
  1. result = data['weatherinfo']
  2. str_temp = ('%s\n%s ~ %s') % (
  3.     result['weather'],
  4.     result['temp1'],
  5.     result['temp2']
  6. )
  7. print str_temp
复制代码
为了防止在请求过程中出错,我加上了一个异常处理。
  1. try:
  2.     ###
  3.     ###
  4. except:
  5.     print '查询失败'
复制代码
以及没有找到城市时的处理:
  1. if citycode:
  2.     ###
  3.     ###
  4. else:
  5.     print '没有找到该城市'
复制代码
45.png

完整代码:
  1. # -*- coding: utf-8 -*-
  2. import urllib2
  3. import json
  4. from city import city

  5. cityname = raw_input('你想查哪个城市的天气?\n')
  6. citycode = city.get(cityname)
  7. if citycode:
  8.     try:
  9.         url = ('http://www.weather.com.cn/data/cityinfo/%s.html'
  10.                % citycode)
  11.         content = urllib2.urlopen(url).read()
  12.         data = json.loads(content)
  13.         result = data['weatherinfo']
  14.         str_temp = ('%s\n%s ~ %s') % (
  15.             result['weather'],
  16.             result['temp1'],
  17.             result['temp2']
  18.         )
  19.         print str_temp
  20.     except:
  21.         print '查询失败'
  22. else:
  23.     print '没有找到该城市'
复制代码
#==== Crossin的编程教室 ====#
微信ID:crossincode
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程


#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

112#
发表于 2018-6-9 00:22:01 |只看该作者
suiersoda 发表于 2018-6-8 13:47
接口得到的字典是嵌套着字典的,尝试着取值成功,但是还不是非常清楚字典嵌套取值这方面的原理,有的写key ...

序号的,说明那一层是list
你要分开来看
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

48

积分

新手上路

Rank: 1

111#
发表于 2018-6-8 13:47:08 |只看该作者
本帖最后由 suiersoda 于 2018-6-8 13:57 编辑

接口得到的字典是嵌套着字典的,尝试着取值成功,但是还不是非常清楚字典嵌套取值这方面的原理,有的写key的名字才可以,有的写序号就可以,还要去重温一下字典方面的知识
  1. #-*- coding: UTF-8 -*-
  2. import urllib.request
  3. import json
  4. from city import city
  5. import gzip

  6. exit=False
  7. while not exit:
  8.     cityname=input('你要查询的城市名称\n输入q退出):')
  9.     if cityname=="q" or cityname=="Q":
  10.         print("退出查询")
  11.         exit=True
  12.     else:
  13.    
  14.         citycode=city.get(cityname)
  15.         if citycode:
  16.             try:
  17.                 url=("http://wthrcdn.etouch.cn/weather_mini?citykey=%s"%citycode)
  18.                 response=urllib.request.urlopen(url).read()
  19.                  #print(response)
  20.                 try:
  21.                     content = gzip.decompress(response).decode("utf-8")
  22.                 except:
  23.                     content=response.decode("utf-8")
  24.                 #print(content)

  25.                 lists=json.loads(content)
  26.                 #print(lists)
  27.                 #print(type(lists))

  28.                 result = lists['data']['forecast'][0]
  29.                 #print(result)
  30.                 str_temp = ('%s,%s\n%s——%s')%(
  31.                     result['date'],
  32.                     result['type'],
  33.                     result['high'],
  34.                     result['low'])

  35.                 print(str_temp)

  36.             except:
  37.                 print('查询失败')

  38.         else:
  39.              print('没有找到该城市')

  40.    

复制代码
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

110#
发表于 2018-5-7 23:56:24 |只看该作者
zhangkai 发表于 2018-5-7 22:20
你好,我自己试了一下发现每次都没有找到城市。完全复制您的代码也是这样,让后我输出citycode发现是none, ...

windows要用gbk
帖子前面有提到
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

4

积分

新手上路

Rank: 1

109#
发表于 2018-5-7 22:20:52 |只看该作者
你好,我自己试了一下发现每次都没有找到城市。完全复制您的代码也是这样,让后我输出citycode发现是none,这是怎么回事
回复

使用道具 举报

0

主题

0

好友

56

积分

注册会员

Rank: 2

108#
发表于 2018-3-29 23:30:22 |只看该作者
xiejiali 发表于 2018-1-12 00:54
原来是少了一层字典,没有看出来,终于搞出来了!
# -*- coding:gbk -*-
import urllib2

太感谢这位大兄弟了,在这里困住好久了!!
回复

使用道具 举报

0

主题

0

好友

4

积分

新手上路

Rank: 1

107#
发表于 2018-1-20 15:35:44 |只看该作者
【添砖加瓦】
Python3 调用urllib获取网络资源、gzip解压的方法:
1、与Python2不同,Python3调用的是urllib.request;
2、与Python2不同,Python3调用gzip模块后,直接使用gzip.decompress()函数解压。
代码如下:

from city import city
import urllib.request
import gzip

cityname=input("请输入你想查询天气的城市名称?\n")
citycode=city.get(cityname)


if citycode:
    url=("http://wthrcdn.etouch.cn/weather_mini?citykey=%s"%citycode)
    print(url)
   
    content=urllib.request.urlopen(url).read()
    content=gzip.decompress(content) .decode("utf-8")
    print(content)
回复

使用道具 举报

0

主题

0

好友

28

积分

新手上路

Rank: 1

106#
发表于 2018-1-12 22:53:42 |只看该作者
crossin先生 发表于 2018-1-12 16:32
调试的时候可以把 try 去掉,方便看报错

好的好的~非常感谢老师~
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

105#
发表于 2018-1-12 16:32:49 |只看该作者
xiejiali 发表于 2018-1-12 00:54
原来是少了一层字典,没有看出来,终于搞出来了!
# -*- coding:gbk -*-
import urllib2

调试的时候可以把 try 去掉,方便看报错
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

28

积分

新手上路

Rank: 1

104#
发表于 2018-1-12 00:54:39 |只看该作者
crossin先生 发表于 2018-1-11 15:30
了解下JSON格式,可以直接整个转成字典

原来是少了一层字典,没有看出来,终于搞出来了!
# -*- coding:gbk -*-
import urllib2
import json

from city import city
from StringIO import StringIO
import gzip

cityname=raw_input('你想查哪个城市的天气?\n')
citycode=city.get(cityname)
print citycode

if citycode:
    try:
        url=('http://wthrcdn.etouch.cn/weather_mini?citykey=%s'%citycode)
        print url
        content=urllib2.urlopen(url).read()
        buf = StringIO(content)
        f = gzip.GzipFile(fileobj=buf)
        data=f.read()
        data2=json.loads(data)
        data3=data2['data']
        data4=data3['forecast'][0]
        str_temp=('%s\n%s\n%s\n%s')%(
            data4['date'],
            data4['type'],
            data4['low'],
            data4['high']
            )
        print str_temp

    except:
        print '查询失败'
else:
    print'没有找到该城市'
  1. ====================== RESTART: D:\Python\lesson 45.py ======================
  2. 你想查哪个城市的天气?
  3. 北京
  4. 101010100
  5. http://wthrcdn.etouch.cn/weather_mini?citykey=101010100
  6. 12日星期五

  7. 低温 -10℃
  8. 高温 -1℃
  9. >>>
  10. ====================== RESTART: D:\Python\lesson 45.py ======================
  11. 你想查哪个城市的天气?
  12. 上海
  13. 101020100
  14. http://wthrcdn.etouch.cn/weather_mini?citykey=101020100
  15. 12日星期五

  16. 低温 -2℃
  17. 高温 5℃
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-22 12:39 , Processed in 0.018697 second(s), 27 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部