据说获取天气预报没有第三方库,可以使用更底层的requests库
先看一下requests库的介绍:
Requests allows you to send organic, grass-fed HTTP/1.1 requests, without the need for manual labor. There's no need to manually add query strings to your URLs, or to form-encode your POST data. Keep-alive and HTTP connection pooling are 100% automatic, thanks to urllib3.
反正就是通讯响应用的咯
安装方法直接pip install requests就好了,在python2.7和python3中都可以调用
首先试着从天气API获取一个JSON文档
有个参考链接:https://www.sojson.com/api/weather.html;https://www.sojson.com/blog/305.html
这种方法简单的理解就是需要将你的请求参数以及请求链接一起用get方式发送出去,来获取你想要的值,然后在输出就好了
参数的话我们需要的是这下,如下
{
"_id": 26,
"id": 26,
"pid": 0,//父ID
"city_code": "",//接口需要的city_code
"city_name": ""
}
那么问题来了,怎么才能或获取city_code呢,真的是绝望,慢慢百度吧
具体脚本如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
def weacode2(address):
parameters={
"_id": 26,
"id": 26,
"pid":0, #父ID
"city_code": "101210101", #接口需要的city_code
"city_name": "杭州"} #需要的参数
base = 'http://t.weather.sojson.com/api/weather/city/101210101' #请求链接
response = requests.get(base, params=parameters)
answer = response.json()
print(answer['cityInfo']['city']) #城市名
print(answer['time']) #当地时间
print('明日天气情况如下:')
print(answer['data']['forecast'][1]) #明天的各种属性
if __name__ == '__main__':
print(weacode2('杭州'))
然后接下来是用原始超文本HTTP来连接,直接上脚本吧,大同小异,主要就是要手动构建path参数的GET查询
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import http.client
import json
from urllib.parse import quote_plus
base = '/api/weather/city/101210101'
def weacode3(address):
path = '{}?address={}&sensor=false'.format(base, quote_plus(address))
connection = http.client.HTTPConnection('t.weather.sojson.com')
connection.request('GET', path)
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode('utf-8'))
print(reply['cityInfo']['city']) #城市名
print(reply['time']) #当地时间
print('明日天气情况如下:')
print(reply['data']['forecast'][1]) #明天的各种属性
if __name__ == '__main__':
if (len(sys.argv) > 1):
address = sys.argv[1]
else:
address = '杭州'
print(address, weacode3(address))
最后一种最底层的做法,其实就是socket通信,比较麻烦的是,比特流和json间的转换,当然不转json,直接将比特流解码后输出也是可以的,但有时候可能只需要一部分内容,而不是全部,根据输出的内容依次找需要的值的定位是个很麻烦的过程,所以肯定还是按照键值对输出比较方便,但是因为这个API属性比较规整,我干脆就直接切成列表吧最后一个元素的值全部输出了,脚本如下
# -*- coding: utf-8 -*-
import socket
import json
from urllib.parse import quote_plus
request_text = """\
GET /api/weather/city/101210101?address={}&sensor=false HTTP/1.1\r\n\
Host: t.weather.sojson.com:80\r\n\
User-Agent: HDU Network Programming Class\r\n\
Connection: close\r\n\
\r\n\
"""
def weacode4(address):
sock = socket.socket()
sock.connect(('t.weather.sojson.com', 80))
request = request_text.format(quote_plus(address))
sock.sendall(request.encode('ascii'))
raw_reply = b''
while True:
more = sock.recv(4096)
if not more:
break
raw_reply += more
sock.close()
reply = raw_reply.decode('utf-8') #解码
reply_arr = reply.split("\n",16) #遇到\n分割,分割16次
#print(type(reply_arr)) #list
print(reply_arr[16]) #所有从API获得的属性
if __name__ == '__main__':
总算完成作业了……