网络库requests

主要介绍以下内容
1.发送HTTP请求
2.设置HTTP请求头
3.抓取二进制数据
4.POST请求
5.响应数据
6.上传文件
7.处理Cookie
8.维持会话
9.SSL证书验证
10.使用代理
11.超时处理
12.身份验证
13.打包请求








一.发送HTTP请求

urllib库中的urlopen方法实际上是以GET方法请求网页,而requests中对应的方法是get,该方法可以接收一个url,然后会返回一个对象,通过get方法的返回值,可以获取HTTP响应数据

1.1使用get方法访问淘宝首页,并获取get方法返回值类型、状态码、响应体、Cookie等信息(出错 SSLError)

import requests
# 屏蔽warning信息
# requests.packages.urllib3.disable_warnings() # 屏蔽也不行,不是urllib3的把,要requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 '}
r = requests.get('https://www.taobao.com',headers=headers) # raise SSLError(e, request=request);
print(type(r))
print(r.status_code)
print(type(r.text))
print(r.cookies)
print(r.text)

get方法返回的是一个requests.model.Response类型的对象

1.2GET请求

要想未get请求指定参数,可以直接将参数加在URL后面,用问号(?)分隔,不过还有另外一种更好的方法,就是使用get方法的params参数,该参数是一个字典类型的值,在字典中每一对key-value,就是一对参数值。如果同时在URL和params参数指定GET请求的参数,那么get方法会将参数合并。如果出现同名的参数,会用列表存储,也就是同名参数的值会按出现的先后顺序保存在列表中
本例使用get方法访问http://httpbin.org/get,并同时使用url和params参数的方式设置GET请求参数,并返回输出结果

import requests
data = {
    'name':'Bill',
    'country':'中国',
    'age':20
}

r = requests.get('http://httpbin.org/get?name=Mike&country=美国&age=40',params=data)
print(r.text)
print(r.json())
print(r.json()['args']['country'])

二.设置HTTP请求头

2.1添加HTTP请求头

使用get方法访问http://httpbin.org/get,并设置了一些请求头,包括User-Agent和一个自定义请求头name,其中name的值为中文

import requests
from urllib.parse import quote,unquote

headers = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
    'name':quote('李宁')
}

r = requests.get('http://httpbin.org/get',headers=headers)
print(r.text)
print('Name:',unquote(r.json()['headers']['Name']))

三.抓取二进制数据

本例使用get方法抓取一个png格式的图像文件,并将其保存为本地文件

import requests

r = requests.get('http://t.cn/EfgN7gz')
print(r.text)
with open('Python从菜鸟到高手.png','wb') as f:
    f.write(r.content)

四。POST请求

在发送POST请求时需要指定data参数,该参数是一个字典类型的值,每一对key-value是一对POST请求参数(表单字段)

import requests
data = {
    'name':'Bill',
    'country':'中国',
    'age':20
}

r = requests.post('http://httpbin.org/post',data=data)
print(r.text)
print(r.json())
print(r.json()['form']['country'])

五。响应数据

使用get方法向简书发送一个请求,然后得到并输出相应的响应结果

import requests

headers = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
}

r = requests.get('http://www.jianshu.com',headers=headers)
print(type(r.status_code),r.status_code)
print(type(r.headers),r.headers)
print(type(r.cookies),r.cookies)
print(type(r.url),r.url)
print(type(r.history),r.history)

if not r.status_code == requests.codes.okay:
    print("failed")
else:
    print("ok")

requests提供了一个code对象,可以直接查看状态码对应的标识(一个字符串),在<requests根目录目录>/requests/status_codes.py

_codes = {

    # Informational.
    100: ('continue',),
    101: ('switching_protocols',),
    102: ('processing',),
    103: ('checkpoint',),
    122: ('uri_too_long', 'request_uri_too_long'),
    200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
    201: ('created',),
    202: ('accepted',),
    203: ('non_authoritative_info', 'non_authoritative_information'),
    204: ('no_content',),
    205: ('reset_content', 'reset'),
    206: ('partial_content', 'partial'),
    207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
    208: ('already_reported',),
    226: ('im_used',),

    # Redirection.
    300: ('multiple_choices',),
    301: ('moved_permanently', 'moved', '\\o-'),
    302: ('found',),
    303: ('see_other', 'other'),
    304: ('not_modified',),
    305: ('use_proxy',),
    306: ('switch_proxy',),
    307: ('temporary_redirect', 'temporary_moved', 'temporary'),
    308: ('permanent_redirect',
          'resume_incomplete', 'resume',),  # These 2 to be removed in 3.0

    # Client Error.
    400: ('bad_request', 'bad'),
    401: ('unauthorized',),
    402: ('payment_required', 'payment'),
    403: ('forbidden',),
    404: ('not_found', '-o-'),
    405: ('method_not_allowed', 'not_allowed'),
    406: ('not_acceptable',),
    407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
    408: ('request_timeout', 'timeout'),
    409: ('conflict',),
    410: ('gone',),
    411: ('length_required',),
    412: ('precondition_failed', 'precondition'),
    413: ('request_entity_too_large',),
    414: ('request_uri_too_large',),
    415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
    416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
    417: ('expectation_failed',),
    418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
    421: ('misdirected_request',),
    422: ('unprocessable_entity', 'unprocessable'),
    423: ('locked',),
    424: ('failed_dependency', 'dependency'),
    425: ('unordered_collection', 'unordered'),
    426: ('upgrade_required', 'upgrade'),
    428: ('precondition_required', 'precondition'),
    429: ('too_many_requests', 'too_many'),
    431: ('header_fields_too_large', 'fields_too_large'),
    444: ('no_response', 'none'),
    449: ('retry_with', 'retry'),
    450: ('blocked_by_windows_parental_controls', 'parental_controls'),
    451: ('unavailable_for_legal_reasons', 'legal_reasons'),
    499: ('client_closed_request',),

    # Server Error.
    500: ('internal_server_error', 'server_error', '/o\\', '✗'),
    501: ('not_implemented',),
    502: ('bad_gateway',),
    503: ('service_unavailable', 'unavailable'),
    504: ('gateway_timeout',),
    505: ('http_version_not_supported', 'http_version'),
    506: ('variant_also_negotiates',),
    507: ('insufficient_storage',),
    509: ('bandwidth_limit_exceeded', 'bandwidth'),
    510: ('not_extended',),
    511: ('network_authentication_required', 'network_auth', 'network_authentication'),
}

六.上传文件

在运行本例之前,应先运行upload_server.py文件
采用的是Post方法的files参数,files参数的值可以是BufferedReader对象,该对象可以用Python语言的内置函数open返回;就是一个字典形式,file为键的字典,值为打开一个文件的对象。

import requests

files1 = {'file':open('Python从菜鸟到高手.png','rb')}
r1 = requests.post('http://127.0.0.1:5000', files=files1)
print(r1.text)
files2 = {'file':open('Python从菜鸟到高手.png','rb')}
r2 = requests.post('http://httpbin.org/post',files=files2)
print(r2.text)

7.处理Cookie(cookie失效,我也不知道如何用cookie返回原有保持cookie的值)

有两种方式设置Coolie:1.headers参数;2.cookies参数

7.1Get和Post方法都有这两个参数,如果使用cookies参数,需要创建RequestsCookieJar对象,并使用set方法设置每一个Cookie

import requests
r1 = requests.get('http://www.baidu.com')
print(r1.cookies)
for key,value in r1.cookies.items():
    print(key,'=',value)

# 获取简书首页内容
headers = {
    'Host':'www.jianshu.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
    'Cookie': 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2226065565%22%2C%22first_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_utm_source%22%3A%22desktop%22%2C%22%24latest_utm_medium%22%3A%22timeline%22%7D%2C%22%24device_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%7D'

}

r2 = requests.get('https://www.jianshu.com',headers=headers)
print(r2.text)

另外一种设置Cookie的方式

requests.cookies.RequestsCookieJar()
jar.set(key,value)

headers = {
    'Host':'www.jianshu.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
}
cookies = 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2226065565%22%2C%22first_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_utm_source%22%3A%22desktop%22%2C%22%24latest_utm_medium%22%3A%22timeline%22%7D%2C%22%24device_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%7D'
jar = requests.cookies.RequestsCookieJar()
for cookie in cookies.split(';'):
    key, value = cookie.split('=',1)
    jar.set(key,value)
r3 = requests.get('http://www.jianshu.com',cookies = jar,headers=headers)
print(r3.text)

八.维持会话(使用同一会话)

在requests中为我们提供了Session对象,可以在无需用户干预Cookie的情况下维持Session.达到不断向服务端发送同一个ID,客户端就可以在服务端找到对应的Session对象,一些爬虫需要作为同一个客户端来多次抓取页面,也就是说这些抓取动作需要在同一个Session中完成。通过Session对象的get、post等方法可以在同一个Session中向服务端发送请求。


这里分别使用传统的方法和Session对象向服务端发送请求,并通过url设置Cookie
可以使用requests.Session()赋值给一个对象,然后改对象再用get请求方式请求url,这样下次请求时就有改cookie字段在返回的响应体中

import requests
# 不使用Session
requests.get('http://httpbin.org/cookies/set/name/Bill')
r1 = requests.get('http://httpbin.org/cookies')
print(r1.text)

# 使用Session
session = requests.Session()
session.get('http://httpbin.org/cookies/set/name/Bill')
r2 = session.get('http://httpbin.org/cookies')
print(r2.text)

不使用Session对象,第二次请求无法获得第一次请求的Cookie.反之,可以

九.SSL证书验证

nginx搭建HTTPPS服务器,然后通过requests发送请求,并捕捉证书验证(待补;nginx在windows下怎么用,如歌生成自己的签名证书 ssl)

十.使用代理(该代理失效)

指定proxies参数,该参数是一个字典类型的值,每一对key-value表示一个代理的协议,如http,https
本例设置了HTTP和HTTPS代理,并通过代理访问天猫首页,最后输出响应内容

import requests
proxies = {
    'http':'http://144.123.68.152:25653',
    'https':'http://144.123.68.152:25653'
}

r = requests.get('https://www.tmall.com/',proxies=proxies)
print(r.text)

十一.超时

import requests,requests.exceptions
try:
    r = requests.get('https://www.jd.com',timeout = 0.001)
    print(r.text)
except requests.exceptions.Timeout as e:
    print(e)

# 抛出连接超时异常
requests.get('https://www.jd.com', timeout=(0.01, 0.001))

# 永久等待,不会抛出超时异常
requests.get('https://www.jd.com', timeout=None)

十二.身份验证

requests包进行身份验证只需设置auth即可,auth参数的值是一个HTTPBasicAuth对象,封装了用户名和密码;运行之前编写的AuthServer.py文件,这是一个支持Basic验证的服务器

import requests

from requests.auth import HTTPBasicAuth

r = requests.get('http://localhost:5000',auth=HTTPBasicAuth('bill','1234'))
print(r.status_code)
print(r.text)

十三.将请求打包

在使用urllib时,可以将请求打包,也就是将所有要发送给服务端的请求信息都放到Request对象中,然后直接发送这个对象即可。requests也可以完成同样工作,在requests中也有一个Request类,用于封装请求信息,然后调用Session的prepare_request方法处理Request对象,并返回一个requests.model.Response对象,最后通过Session.send方法发送Response对象


本例使用Request对象封装请求,通过Session.send方法发送请求,然后输出响应结果

from requests import Request,Session

url = 'http://httpbin.org/post'

data = {
    'name':'Bill',
    'age':30
}
headers = {
    'country':'China'
}

session = Session()
req = Request('post',url,data=data,headers=headers)
prepared = session.prepare_request(req)
r = session.send(prepared)
print(type(r))
print(r.text)
posted @ 2021-09-04 21:24  索匣  阅读(89)  评论(0编辑  收藏  举报