机器学习基础(7)-Python3网络请求

Python3网络请求

本文主要介绍Python3网络请求的所使用的的模块request

  • request是Python社区中最喜欢的库,因为它简洁易用。 request由urllib3提供支持,有玩笑说这是“唯一的非转基因HTTP库,适合人类消费”。
  • request抽象了大量的程式化的代码,使得HTTP请求比使用内置urllib库更简单。
1. 安装

首先用pip进行安装

pip install requests
2. 模块说明
  • requests是使用Apache2 licensed 许可证的HTTP库。
  • 用python编写。
  • 比urllib2模块更简洁。
  • request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。
  • 在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用requests可以轻而易举的完成浏览器可有的任何操作。
  • 现代,国际化,友好。
  • requests会自动实现持久连接keep-alive
3. 基础入门

1)导入模块

import requests

2)发送请求的简洁

示例代码:获取一个网页(百度)

import requests  
r = requests.get('https://www.baidu.com')       # 最基本的不带参数的get请求
r1 = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'})      # 带参数的get请求

我们就可以使用该方式使用以下各种方法

requests.get(‘https://www.test.com/timeline’)                                # GET请求
requests.post(“http://www.test.com/post”)                                    # POST请求
requests.put(“http://www.test.com/put”)                                      # PUT请求
requests.delete(“http://www.test.com/delete”)                                # DELETE请求
requests.head(“http://www.test.com/get”)                                     # HEAD请求
requests.options(“http://www.test.com/get” )                                 # OPTIONS请求

3)为url传递参数

url_params = {'key':'value'}       # 字典传递参数,如果值为None的键不会被添加到url中
r = requests.get('your url',params = url_params) 
print(r.url)  

输出结果为:

your url?key=value

4)响应的内容

字段 含义
r.encoding #获取当前的编码
r.encoding = 'utf-8' #设置编码
r.text #以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。
r.content #以字节形式(二进制)返回。字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩。
r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
r.status_code #响应状态码
r.raw #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read()
r.ok # 查看r.ok的布尔值便可以知道是否登陆成功
r.json() #Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常
r.raise_for_status() #失败请求(非200响应)抛出异常

post发送json请求:

import requests
import json
 
r = requests.post('https://api.apiopen.top/getJoke', data=json.dumps({'id': 'data'}))
print(r.json())

5)定制头和cookie信息

header = {'user-agent': 'my-app/0.0.1''}
cookie = {'key':'value'}
r = requests.get/post('your url',headers=header,cookies=cookie)
import requests 
import json

data = {'id': 'data'}
headers = {'content-type': 'application/json', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}

r = requests.post('https://api.apiopen.top/getJoke', data=json.dumps({'id': 'data'}, headers=headers) 
print(r.text)

6)响应状态码

  • 使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……
  • 获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。
r = requests.get('http://www.baidu.com')
print(r.text, '\n{}\n'.format('*'*79), r.encoding)
r.encoding = 'GBK'
print(r.text, '\n{}\n'.format('*'*79), r.encoding)

示例代码:

# -*- coding: utf-8 -*-
# 打印中文需要的内容 开始
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
# 打印中文需要的内容 结束

import requests

r = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'})  # 带参数的get请求

print(r.url)
print(r.status_code)     # 获取返回状态
print(r.text)            # 打印解码后的返回数据

运行结果:

https://api.apiopen.top/musicDetails?id=604392760
200
{"code":200,"message":"成功!","result":{"xcode":"","songList":""}}

7)响应

字段 描述
r.headers #返回字典类型,头信息
r.requests.headers #返回发送到服务器的头信息
r.cookies #返回cookie
r.history #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向</pre>

8)超时

r = requests.get('url',timeout=1)           #设置秒数超时,仅对于连接有效

9)会话对象,能够跨请求保持某些参数

s = requests.Session()
s.auth = ('auth','passwd')
s.headers = {'key':'value'}
r = s.get('url')
r1 = s.get('url1') 

10)代理

proxies = {'http':'ip1','https':'ip2' }
requests.get('url',proxies=proxies)

汇总:

# HTTP请求类型 # get类型
requests.get(‘https://www.test.com/timeline’)                                # GET请求
requests.post(“http://www.test.com/post”)                                    # POST请求
requests.put(“http://www.test.com/put”)                                      # PUT请求
requests.delete(“http://www.test.com/delete”)                                # DELETE请求
requests.head(“http://www.test.com/get”)                                     # HEAD请求
requests.options(“http://www.test.com/get” )                                 # OPTIONS请求
print(r.content) #以字节的方式去显示,中文显示为字符
print(r.text)    #以文本的方式去显示

#URL传递参数
payload = {'tel': '18812345678'}
r = requests.get("https://tcc.taobao.com/cc/json/mobile_tel_segment.htm", params=payload) 
print(r.url) #示例为https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=18812345678

#获取/修改网页编码
r = requests.get('https://www.baidu.com') 
print (r.encoding) 

#json处理
r = requests.get('https://api.apiopen.top/musicDetails') 
print(r.json()) # 需要先import json 

# 定制请求头
url = 'https://www.baidu.com'
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
r = requests.post(url, headers=headers) 
print (r.request.headers) 

#复杂post请求
url = 'https://www.baidu.com' 
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))  #如果传递的payload是string而不是dict,需要先调用dumps方法格式化一下

# post多部分编码文件
url = 'https://www.baidu.com' 
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files) # 响应状态码
r = requests.get('http://m.ctrip.com') 
print(r.status_code) # 响应头
r = requests.get('http://m.ctrip.com') 
print (r.headers) 
print (r.headers['Content-Type']) 
print (r.headers.get('content-type')) #访问响应头部分内容的两种方式

# Cookies
url = 'https://www.baidu.com' 
r = requests.get(url)
r.cookies['example_cookie_name']    #读取cookies
url = 'http://m.ctrip.com/cookies' 
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies) #发送cookies

#设置超时时间
r = requests.get('https://www.baidu.com', timeout=0.001) #设置访问代理
proxies = { 
               "http": "http://10.10.1.10:3128", 
               "https": "http://10.10.1.100:4444"
          }
r = requests.get('http://m.ctrip.com', proxies=proxies)

#如果代理需要用户名和密码,则需要这样:
proxies = {
              "http": "http://user:password@10.10.1.10:3128/",
           }

4、示例代码

1) GET请求

# -*- coding: utf-8 -*-
# 打印中文需要的内容 开始
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
# 打印中文需要的内容 结束

import requests

# 无参数请求
r = requests.get(url='https://m.baidu.com')

print(r.url)
print(r.status_code)     # 获取返回状态
print(r.text) 

# 有参数请求
r = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'})  # 带参数的get请求

print(r.url)
print(r.status_code)     # 获取返回状态
print(r.text)            # 打印解码后的返回数据

2) POST请求

# 1、基本POST实例
import requests

payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.post("https://www.baidu.com", data=payload) 
print(ret.text) 

# 2、发送请求头和数据实例
import requests import json

url = 'https://www.baidu.com' 
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}

ret = requests.post(url, data=json.dumps(payload), headers=headers) 
print(ret.text) 
print(ret.cookies)

3) json请求:

#! /usr/bin/python3
import requests
import json

class url_request(): 
     def __init__(self):
        ''' init '''

if __name__ == '__main__': 
     heard = {'Content-Type': 'application/json'} 
     payload = {'CountryName': '中国', 
                'ProvinceName': '四川省', 
                'L1CityName': 'chengdu', 
                'L2CityName': 'yibing', 
                'TownName': '', 
                'Longitude': '107.33393', 
                'Latitude': '33.157131', 
                'Language': 'CN'} 
     r = requests.post("http://www.xxxxxx.com/CityLocation/json/LBSLocateCity", heards=heard, data=payload) 
     data = r.json() 
     if r.status_code!=200: 
         print('LBSLocateCity API Error' + str(r.status_code)) 
     print(data['CityEntities'][0]['CityID'])  # 打印返回json中的某个key的value
     print(data['ResponseStatus']['Ack']) 
     print(json.dump(data, indent=4, sort_keys=True, ensure_ascii=False))  # 树形打印json,ensure_ascii必须设为False否则中文会显示为unicode</pre>

4) Xml请求:

#! /usr/bin/python3
import requests 
 
class url_request(): 
     def __init__(self):
         """init"""
 
if __name__ == '__main__':
     heards = {'Content-type': 'text/xml'} 
     XML = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Request xmlns="http://tempuri.org/"><jme><JobClassFullName>WeChatJSTicket.JobWS.Job.JobRefreshTicket,WeChatJSTicket.JobWS</JobClassFullName><Action>RUN</Action><Param>1</Param><HostIP>127.0.0.1</HostIP><JobInfo>1</JobInfo><NeedParallel>false</NeedParallel></jme></Request></soap:Body></soap:Envelope>'
     url = 'http://jobws.push.mobile.xxxxxxxx.com/RefreshWeiXInTokenJob/RefreshService.asmx'
     r = requests.post(url=url, heards=heards, data=XML) 
     data = r.text 
     print(data)

5) 状态异常处理

import requests
 
URL = 'http://ip.taobao.com/service/getIpInfo.php'  # 淘宝IP地址库API
try:
     r = requests.get(URL, params={'ip': '8.8.8.8'}, timeout=1)
     r.raise_for_status()  # 如果响应状态码不是 200,就主动抛出异常
 except requests.RequestException as e: 
     print(e)
 else: 
     result = r.json() 
     print(type(result), result, sep='\n')

6) 上传文件

使用request模块,也可以上传文件,文件的类型会自动进行处理:

import requests

url = 'http://127.0.0.1:8080/upload' 
files = {'file': open('/home/rxf/test.jpg', 'rb')} 
#files = {'file': ('report.jpg', open('/home/lyb/sjzl.mpg', 'rb'))}     #显式的设置文件名
r = requests.post(url, files=files) 
print(r.text)

request更加方便的是,可以把字符串当作文件进行上传:

import requests

url = 'http://127.0.0.1:8080/upload' 
files = {'file': ('test.txt', b'Hello Requests.')}     #必需显式的设置文件名
r = requests.post(url, files=files) 
print(r.text)

7) 身份验证

基本身份认证(HTTP Basic Auth)

import requests from requests.auth 
import HTTPBasicAuth

r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd')) 
# r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=('user', 'passwd'))    # 简写
print(r.json())

另一种非常流行的HTTP身份认证形式是摘要式身份认证,Requests对它的支持也是开箱即可用的:

requests.get(URL, auth=HTTPDigestAuth('user', 'pass'))

8) Cookies与会话对象

如果某个响应中包含一些Cookie,你可以快速访问它们:

import requests

r = requests.get('http://www.google.com.hk/') print(r.cookies['NID']) print(tuple(r.cookies))

要想发送你的cookies到服务器,可以使用 cookies 参数:

import requests

url = 'http://httpbin.org/cookies' 
cookies = {'testCookies_1': 'Hello_Python3', 'testCookies_2': 'Hello_Requests'} 
# 在Cookie Version 0中规定空格、方括号、圆括号、等于号、逗号、双引号、斜杠、问号、@,冒号,分号等特殊符号都不能作为Cookie的内容。
r = requests.get(url, cookies=cookies) print(r.json())

会话对象让你能够跨请求保持某些参数,最方便的是在同一个Session实例发出的所有请求之间保持cookies,且这些都是自动处理的,甚是方便。
下面就来一个真正的实例,如下是快盘签到脚本:

import requests

headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, compress', 'Accept-Language': 'en-us;q=0.5,en;q=0.3', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}

s = requests.Session()
s.headers.update(headers) # s.auth = ('superuser', '123')
s.get('https://www.kuaipan.cn/account_login.htm')

_URL = 'http://www.kuaipan.cn/index.php' s.post(_URL, params={'ac':'account', 'op':'login'},
       data={'username':'****@foxmail.com', 'userpwd':'********', 'isajax':'yes'})
r = s.get(_URL, params={'ac':'zone', 'op':'taskdetail'}) 
print(r.json())
s.get(_URL, params={'ac':'common', 'op':'usersign'})</pre>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。