机器学习基础(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>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351