python3爬虫(一):请求库之requests

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Song_Lynn/article/details/82944927

python3爬虫(一):请求库之requests

Request是基于urllib编写、采用Apache2 Licensed开源协议的HTTP库,在使用方面Requests比urllib更加方便

一、HTTP请求

1. GET

requests.get(url [, params={‘key’: ‘value’}])

  • 通过url的查询字符串传递数据时,数据以键值对的形式跟在url的一个问号之后
  • Requests允许使用params关键字参数传递数据

注意:

  • 字典中值为None的键不会添加到查询字符串中
  • 键值可以是列表
import requests

# 无查询字符串
res1 = requests.get('http://www.baidu.com')

# 有查询字符串
data2 = {
	'key1': 'value1',
	'key2': 'value2'
}
res2 = requests.get('http://www.xxx.com', params=data)
print(res2)		# http://www.xxx.com?key1=value1&key2=value2

# 查询字符串中有列表
data3 = {
	'key1': 'value1',
	'key2': ['value2', 'value3']
}
res3 = requests.get('http://www.xxx.com', params=data)
print(res3)		# http://www.xxx.com?key1=value1&key2=value2&key2=value3

2. POST

requests.post(url [, data={‘key’: ‘value’}, json={‘key’: ‘value’}])

  • 以字典形式提交表单数据
  • 可以传入一个元组列表,尤其是表单中多个元素使用同一key
  • 发送数据并非编码为表单形式。如传递一个string,会被直接发布出去
  • 除自行对dict进行编码,可以使用json参数直接传递,会被自动编码
import requests

url = 'http://www.xxx.com'

# 传递字典
data1 = {
	'name': '12345',
	'age': '23'
}
res1 = requests.post(url, data=data1)

# 传递元组
data2 = (('key1', 'value1'), ('key1', 'value2'))
res2 = requests.post(url, data=data2)

import json
data3 = {'some': 'data'}
res3 = requests.post(url, data=json.dumps(payload))

# 数据未编码
data4 = {'some': 'data'}
res4 = requests.post(url, json=data4)

3. PUT

requests.put(url [, data={‘key’: ‘value’}])
以字典形式提交表单数据

import requests

url = 'http://www.xxx.com'
data = {
	'name': '12345',
	'age': '23'
}
res = requests.put(url, data=data)

4. DELETE

requests.delete(url)

import requests
res = requests.delete(url)

5. HEAD

requests.head(url)

import requests
res = requests.head(url)

6. OPTIONS

requests.options(url)

import requests
res = requests.options(url)

二、头部信息

  • 为所有请求(get, post, put, delete等)添加HTTP头部信息,只需要传递一个字典dict给headers参数
  • 所有的header值类型:string, bytestring, unicode(不建议使用unicode)
  • 大小写不敏感

注意:定制header的优先级低于某些特定的信息源

import requests

url = 'http://www.baidu.com'
headers = {'user-agent': 'xxxxxxxxxxxxxx'}
res = requests.get(url, headers=headers)

三、Respone对象

使用requests方法后,会返回 respone 对象,存储了服务器相应内容

  • res.text:读取已被解码的服务器响应的内容
    • 基于HTTP头部对响应的编码作出的推测进行内容编码
    • 能够使用 res.encoding 来改变编码方式
import requests
res - requests.get('https://api.github.com/events')
pirnt(res.text)		# u'[{"repository":{"open_issues":0,"url":"https://github.com/...
  • res.encoding:响应内容的编码方式
    • getter:查询当前响应内容的编码方式
    • setter:改变当前响应内容的编码方式
  • res.content:二进制响应内容
    • 以字节的形式访问请求响应体
    • 会自动解码 gzip 和 deflate 传输编码的响应数据
import requests
res - requests.get('https://api.github.com/events')
pirnt(res.content)		# b'[{"repository":{"open_issues":0,"url":"https://github.com/...

# 请求返回的二进制数据创建一张图片
from PIL import Image
from io import BytesIO
i = Image.open(BytesIO(res.content))
  • res.json():返回JSON数据
    • 内置的JSON解码器,有助于处理JSON数据
    • 解码失败,则会抛出一个异常

注意:调用 res.json() 成功不意味着响应成功(有时响应失败也会包含一个JSON对象)

import requests
res - requests.get('https://api.github.com/events')
pirnt(res.json())		# [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
  • res.raw:原始响应内容
    • 在初始请求中设置 stream=True
    • 可以使用 res.iter_content(xxx)处理大量直接使用 res.raw 不得不处理的
res = requests.get('https://api.github.com/events', stream=True)
print(res.raw)		# <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
print(res.raw.read(10))		# '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

# 一般情况下,以下面的模式将文本刘保存到文件
with open(filename, 'wb') as fd:
	for chunk in r.iter_content(chunk_size):
		fd.write(chunk)
  • res.status_code:检测响应的状态码
    • 可以使用 Requests 内置的状态码 requests.codes.xx 查询对象
res = resquests.get('http://www.xxx.com')
print(res.status_code)		# 200
print(res.status_code == requests.code.ok)		# True
  • res.raise_for_status():抛出异常

    • 当发送了错误请求,可使用 res.raise_for_status() 来抛出异常
    • 当发送了正确请求时,res.raise_for_status()返回None
  • res.headers:查看服务器响应头

    • 以字典 dict 形式展示响应头
    • 大小写不敏感
    • 服务器可以多次接受同一header,每次都使用不同的值,但Requests胡将它们合并
  • res.cookies:访问响应中的cookie

  • res.history:追踪重定向

四、Cookie

1. 访问cookies

使用 respone.cookies 访问服务器响应中包含的cookie

url = 'http://www.xxx.com'
res = requests.get(url)
print(res.cookies)

2. 发送cookies

  • 发送HTTP请求时,使用 cookies 参数
  • 类型:
    • 字典 dict
    • RequestsCookieJar对象(行为与字典类似,但接口更为完整,适合跨域名、跨路径使用)
url = 'http://www.xxx.com'

cookies1 = {'key': 'value'}
res1 = requests.get(url, cookies.cookies1)

cookies2  = requests.cookies.RequestsCookieJar()
cookies2.set('key', 'value', domain='...', path='...')		# domain:有效域,path:有效路径
res2 = resquests.get(url, cookies=cookies2)

五、文件上传

发型POST请求时,使用 files 文件

  • 上传多部分编码(Multipart-Encoded)文件
url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
res = requests.post(url, files=files)
  • 显示地设置文件名、文件类型、请求头
url = 'http://httpbin.org/post'
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
res = requests.post(url, files=files)
  • 发送作为文件来接受的字符串
url = 'http://httpbin.org/post'
files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
 res = requests.post(url, files=files)

注意:

  • 发送一个非常大的文件作为 multipart/form-data 请求,requests不支持将请求做成数据流,但第三方包 requests-toolbelt支持
  • 强烈建议用二进制模式(binary mode)打开文件(原因:Requests试图提供Content-Length header,会被设为文件的字节数),而不是文本模式(text mode)

六、重定向与请求历史

  • 默认情况下,除了HEAD,Requests会自动处理所有重定向
  • res.history是一个response对象的列表,按照从最老到最近的请求进行排序
  • get, post, put, patch, delete, options请求可以通过 allow_redirects参数禁用重定向处理
  • head请求也可以使用 allow_redirects 启用重定向
    allow_redirects:默认为 True(启用)

七、超时 timeout

  • 发送HTTP请求时,使用 timeout参数设定超时时间以停止等待响应
  • 一般都应使用该参数
  • 仅对连接过程有效,与响应提的下载无关

八、错误与异常

所有显示抛出的异常都继承自Requests.exceptions.RequestException

  • 网络问题(DNS查询失败、拒绝连接等):Requests抛出 ConnectionError异常
  • HTTP请求返回了不成功的状态码:Response.raise_for_status()抛出HTTPError异常
  • 请求超时:Timeout异常
  • 请求超过了设定的最大重定向次数:TooManyRedirects异常

猜你喜欢

转载自blog.csdn.net/Song_Lynn/article/details/82944927