从获取城市的天气预报到了解网络编程

据说获取天气预报没有第三方库,可以使用更底层的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__':

总算完成作业了……

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值