之前做了个日本的网测题,题目的内容是call一个web上面的api并且返回结果。之前一直不知道这道题是在干什么,这两天终于搞明白了
参考资料
关于request
一个Python的第三方库,用于访问网络资源
需要导入模块import requests
小知识:http协议(居然现在才发现我连这个都不知道)
- http是超文本传输协议的缩写,是从www服务器传输超文本到本地浏览器的传输协议
- http协议作用于客户端-服务器架构上,浏览器作为http的客户端,通过url向http服务器端(web服务器)发送所有请求,web服务器在接到请求后,向客户端发送响应
特点
- 简单快捷。客户端请求的时候,只需要request method(包括GET,HEAD,POST等)和url。每种方法规定的客户和服务器的连接类型不同。因为协议简单,所以服务器的程序规模小,反应快速
- 灵活:允许传输任意类型的对象
- 无连接:限制每次连接只处理一个请求,收到客户端的应答后断开连接
- 无状态:对于事物的处理没有记忆能力,所以如果处理的时候需要先前的信息就需要全部重新传输
- B/S(浏览器,服务器-广域网),C/S(客户端,服务器-局域网)模式
URL(Uniform Resource Locator)
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
一个URL包括几部分:
- 协议部分:http:,表示用的这个协议(https是加密的协议)
- 域名部分:
www.aspxfans.com
,也可以用IP地址作为域名 - 端口,用冒号分割,不是必须的
- 虚拟目录(endpoint),从第一个/到最后一个/,也不是必须的
- 文件名,从最后一个/到?为止。如果没有?就是到#。如果都没有就是到最后。如果省略的话就是默认文件名
- 参数部分:从?到#,不是必须的。用来搜索和查询。可以有多个参数,参数之间&相隔
- 锚部分,从#开始到最后,不是必须的
客户端发送的request
当客户端向服务器发送请求的时候,包括以下的四个部分:
request line,header,empty line, request data
- 请求行,会说明method(比如GET),要访问的资源,http版本
- 请求头部:说明服务器要使用的附加信息(多行)
- 空行:请求头部后面需要有空行
- 请求数据(主体),可以为空
服务器响应的response
分为状态行,消息报头,空行,和响应正文
- 状态行:http的版本号,状态码(200),状态消息(ok)
- 消息报头:客户端需要使用的附加信息
- 空行
- html部分为响应正文
关于状态码
- 200 ok 成功
- 3xx 重定向,必须完成更进一步的操作
- 4xx 客户端错误,请求有语法错误或者无法实现
- 5xx 服务端错误,服务器未能实现
1 | 200 OK //客户端请求成功 |
工作原理
- 客户端(浏览器)连接到服务器,和服务器的http端口简历TCP连接(TCP:一种传输协议)
- 发送http请求
- 服务器接收并返回响应
- 释放连接TCP,可能会由服务器断线,可能会保持一段时间
- 客户端解析html的内容,显示
小知识:关于post和get
- GET请求,请求数据会附在URL后面,用?分割(比如传入参数的时候)
- 如果是英语或数字,原样
- 如果是空格换成+
- 如果是中文或者其他字符,直接把字符串加密得到16进制ASCII
- 所以GET提交的数据会在地址栏显示出来,但是POST会把结果放在包体里面,不改变
- 传输数据大小:
- URL对数据的大小没有限制,但是有些浏览器可能会限制URL的字符长度,导致GET不行
- 安全性:
- POST的安全性更高。
- 但是http本身就是明文协议,所以其实哪个都安全性不高。最主要的方法是https
回到request本身
发送请求
我们可以使用get命令获取某个网页的信息,然后从名字为r的对象里面得到后续需要的信息
我们可以用r.url来打印现在的url等1
r = requests.get('https://api.github.com/events')
传递参数
requests支持用params关键字来传输参数,参数设置在dict里面1
2payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
响应内容
响应的内容可以用r.text
来限时,request会根据http头部的编码对文本进行解码,可以用r.encoding
来查看解码类型并且改变
二进制响应内容
可以用字节的方式来访问响应体r.content
,会自动解码
Json响应内容
内置json解码器,可以处理json数据。r.json()
如果解码失败,会抛出异常401
原始响应内容
r.raw
实际应用
所以在一道例题中,需要调用某个网站的api,得到输入数字的hash值
- http方法:GET
- 参数:”q”,生成hash的文字列
- 响应:两个key的json,分别是’n’和’hash’
1
2
3
4
5
6
7
8
9
10
11
12import requests
# the input data
param = 'n'
url = 'http://challenge-server.code-check.io'
endpoint = '/api/hash'
param = {'q': param}
r = requests.get(url + endpoint, params=param)
# r = requests.get(url)
print(r.json())