Python的request库

之前做了个日本的网测题,题目的内容是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
2
3
4
5
6
7
200 OK                        //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

工作原理

  • 客户端(浏览器)连接到服务器,和服务器的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
2
payload = {'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
    12
    import 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())