爬虫相关--requests库

requests的理想:HTTP for Humans

1|0一、八个方法

相比较urllib模块,requests模块要简单很多,但是需要单独安装:

  • 在windows系统下只需要在命令行输入命令 pip install requests 即可安装。
  • 在 linux 系统下,只需要输入命令 sudo pip install requests ,即可安装。

requests库的八个主要方法

方法描述
requests.request() 构造一个请求,支持以下各种方法
requests.get() 向html网页提交get请求的方法
requests.post() 向html网页提交post请求的方法
requests.head() 获取html头部信息的主要方法
requests.put() 向html网页提交put请求的方法
requests.options() 向html网页提交options请求的方法
requests.patch() 向html网页提交局部修改的请求
requests.delete() 向html网页提交删除的请求

请求之后,服务器通过response返回数据,response具体参数如下图:

属性描述
r.status_code http请求的返回状态,若为200则表示请求成功
r.text http响应内容的字符串形式,即返回的页面内容
r.encoding 从http header 中猜测的相应内容编码方式
r.apparent_encoding 从内容中分析出的响应内容编码方式(备选编码方式)
r.content http响应内容的二进制形式
r.headers 响应头
r.cookies cookie
r.url url
r.history 请求历史

2|0requests.request(method, url, **kwargs)

  • method:即 get、post、head、put、options、patch、delete
  • url:即请求的网址
  • **kwargs:控制访问的参数,具体参数如下:

2|1params

字典或字节序列,作为参数增加到url中。使用这个参数可以把一些键值对以?key1=value1&key2=value2的模式增加到url中

## request(method, url, **kwargs),当 **kwargs 为 params import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.request('GET', 'http://httpbin.org/get', params=payload) print(r.url) # result: http://httpbin.org/get?key1=value1&key2=value2 print(r.text) # result: # { # "args": { # "key1": "value1", # "key2": "value2" # }, # "headers": { # "Accept": "*/*", # "Accept-Encoding": "gzip, deflate", # "Connection": "close", # "Host": "httpbin.org", # "User-Agent": "python-requests/2.19.1" # }, # "origin": "1.203.183.95", # "url": "http://httpbin.org/get?key1=value1&key2=value2" # }

2|2data

字典,字节序或文件对象,重点作为向服务器提供或提交资源是提交,作为request的内容,与params不同的是,data提交的数据并不放在url链接里, 而是放在url链接对应位置的地方作为数据来存储。它也可以接受一个字符串对象。

## request(method, url, **kwargs),当 **kwargs 为 data import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.request('POST', 'http://httpbin.org/post', data=payload) print(r.url) # result: http://httpbin.org/post print(r.text) # result: # { # "args": {}, # "data": "", # "files": {}, # "form": { # "key1": "value1", # "key2": "value2" # }, # "headers": { # "Accept": "*/*", # "Accept-Encoding": "gzip, deflate", # "Connection": "close", # "Content-Length": "23", # "Content-Type": "application/x-www-form-urlencoded", # "Host": "httpbin.org", # "User-Agent": "python-requests/2.19.1" # }, # "json": null, # "origin": "1.203.183.95", # "url": "http://httpbin.org/post" # }

2|3json

json格式的数据, json合适在相关的html,http相关的web开发中非常常见, 也是http最经常使用的数据格式, 他是作为内容部分可以向服务器提交。

## request(method, url, **kwargs),当 **kwargs 为 json import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.request('POST', 'http://httpbin.org/post', json=payload) print(r.url) # result: http://httpbin.org/post print(r.text) # result: # { # "args": {}, # "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", # "files": {}, # "form": {}, # "headers": { # "Accept": "*/*", # "Accept-Encoding": "gzip, deflate", # "Connection": "close", # "Content-Length": "36", # "Content-Type": "application/json", # "Host": "httpbin.org", # "User-Agent": "python-requests/2.19.1" # }, # "json": { # "key1": "value1", # "key2": "value2" # }, # "origin": "1.203.183.95", # "url": "http://httpbin.org/post" # }

2|4files

注意点: Content-Type: multipart/form-data; boundary=${bound}这个 headers不要传入

上传文件的的接口参数的类型为content-type:multipart/form-data,那么我们使用requests来发送请求的时候,接口中文件上传的参数需要使用files来传递。files参数格式如下

# fiels为字典类型数据,上传的文件为键值对的形式,参数名作为键, # 参数值是一个元组,内容为以下格式(文件名,打开的文件流,文件类型) files = { "pic": ("test01.gif", open("test01.gif", "rb"), "images/git") } # 注意点:除了上传的文件,接口其他参数不能放入files

文件上传的参数准备好了,那么接口中其他的参数怎么处理呢?其他的参数使用data传递即可。参数组织如下:

# 其他的参数 data = { "nickname": "木森", "age": 18, "sex": "男", }

单文件上传

import requests # 如何请求文件上传的接口 url = "http://127.0.0.1:5000/upload" # 上传的文件参数 files = { "pic": ("test01.gif", open("test01.gif", "rb"), "images/gif") } # 其他的参数 data = { "nickname": "木森", "age": 18, "sex": "男", } # 发送请求 response = requests.post(url=url, files=files, data=data) # 打印结果 print(response.json())

多文件上传

import requests data = { "name": "hangge.com", "age": 100 } files = [ ('file1', ('1.png', open('logo.png', 'rb'), 'image/png')), ('file2', ('2.png', open('logo.png', 'rb'), 'image/png')) ] response = requests.post('http://www.hangge.com/upload.php', data=data, files=files) print(response.text)

2|5流式上传文件

1,requests-toolbelt 扩展库

(1)有时我们需要上传一个非常大的文件(比如 1G 左右),如果像上面的方式直接使用 Requests 提交,可能会造成内存不足而崩溃。
(2)所以发送大文件时还是建议将请求做成数据流。不过默认下 Requests 不支持流式上传,但有个第三方包 requests-toolbelt 是支持的(本质还是 multipart/form-data 上传)
(3)在使用 requests-toolbelt 之前,我们首先通过 pip 进行安装:
pip install requests-toolbelt

2,使用流式上传文件

下面样例我们使用 requests-toolbelt 来实现文件的流式上传:
  • 不同于 requests 全部读到内存中上传,requests-toolbelt 是边读边上传
  • 其本质还是 multipart/form-data 提交数据,所以服务端代码不需要变化。
import requests from requests_toolbelt import MultipartEncoder m = MultipartEncoder( fields={'name': 'hangge.com', "age": '100', 'file1': ('1.png', open('logo.png', 'rb'), 'image/png'), 'file2': ('2.png', open('logo.png', 'rb'), 'image/png')} ) r = requests.post('http://www.hangge.com/upload.php', data=m, headers={'Content-Type': m.content_type}) print(r.text)

3,监听上传进度

requests-toolbelt 还提供了个监视器(MultipartEncoderMonitor),该监视器接受一个回调函数,我们可以在回调中实时跟踪进度。

import requests from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor def my_callback(monitor): progress = (monitor.bytes_read / monitor.len) * 100 print("\r 文件上传进度:%d%%(%d/%d)" % (progress, monitor.bytes_read, monitor.len), end=" ") e = MultipartEncoder( fields={'name': 'hangge.com', "age": '100', 'file1': ('1.png', open('logo.png', 'rb'), 'image/png'), 'file2': ('2.png', open('logo.png', 'rb'), 'image/png')} ) m = MultipartEncoderMonitor(e, my_callback) r = requests.post('http://www.hangge.com/upload.php', data=m, headers={'Content-Type': m.content_type}) print(r.text)

2|6headers

字典是http的相关语,对应了向某个url访问时所发起的http的头字段, 可以用这个字段来定义http的访问的http头,可以用来模拟任何我们想模拟的浏览器来对url发起访问。

## request(method, url, **kwargs),当 **kwargs 为 headers import requests payload = {'key1': 'value1', 'key2': 'value2'} headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"} r = requests.request('GET', 'http://httpbin.org/get', params=payload, headers=headers) print(r.url) # result: http://httpbin.org/get?key1=value1&key2=value2 print(r.text) # result: # { # "args": { # "key1": "value1", # "key2": "value2" # }, # "headers": { # "Accept": "*/*", # "Accept-Encoding": "gzip, deflate", # "Connection": "close", # "Host": "httpbin.org", # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36" # }, # "origin": "1.203.183.95", # "url": "http://httpbin.org/get?key1=value1&key2=value2" # }

2|7cookies

字典或CookieJar,指的是从http中解析cookie

## request(method, url, **kwargs),当 **kwargs 为 cookies import requests cookies = dict(cookies_are='working') r = requests.request('GET', 'http://httpbin.org/cookies', cookies=cookies) print(r.url) # result: http://httpbin.org/cookies print(r.text) # result: # { # "cookies": { # "cookies_are": "working" # } # }

把cookie对象转换成字典

requests.utils.dict_from_cookiejar()

把cookie值转换成Python的字典形式

requests.utils.cookiejar_from_dict()


把Python的字典生成cookiejar形式

import requests def main(): url = 'https://www.csdn.net/' response = requests.get(url) print(response.cookies) # 返回的结果为requests.cookies.RequestsCookieJar类型 # 把cookie值转换成Python的字典类型 print(requests.utils.dict_from_cookiejar(response.cookies)) # 返回的结果为字典类型 data = {'dc_session_id': '10_1578585500018.380464', 'uuid_tt_dd': '10_30291552180-1578585500018-204559', 'acw_tc': '2760829e15785855000142693e932dc23200dbf1d6a5e569f5a0bacfe97297'} print(requests.utils.cookiejar_from_dict(data))

 

2|8会话维持

  在requests中,如果直接利用get()或post()等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。这时候就需要采用会话。

import requests s = requests.Session() s.get("http://httpbin.org/cookies/set/number/123456789") r = s.get('https://httpbin.org/cookies') print(r.text)

2|9auth

元组,用来支持http认证功能

## request(method, url, **kwargs),当 **kwargs 为 auth import requests cs_user = '用户名' cs_psw = '密码' r = requests.request('GET', 'https://api.github.com', auth=(cs_user, cs_psw)) print(r.url) # result: 待补充 print(r.text) # result: 待补充

2|10timeout

用于设定超时时间, 单位为秒,当发起一个get请求时可以设置一个timeout时间, 如果在timeout时间内请求内容没有返回, 将产生一个timeout的异常。

## request(method, url, **kwargs),当 **kwargs 为 timeout import requests r = requests.request('GET', 'http://github.com', timeout=0.001) print(r.url) # result: 报错 socket.timeout: timed out

2|11proxies

字典, 用来设置访问代理服务器。

## request(method, url, **kwargs),当 **kwargs 为 proxies import requests proxies = { 'https': 'http://41.118.132.69:4433' } # 也可以通过环境变量设置代理 # export HTTP_PROXY='http://10.10.1.10:3128' # export HTTPS_PROXY='http://10.10.1.10:1080' r = requests.request('GET', 'http://httpbin.org/get', proxies=proxies) print(r.url) # result: http://httpbin.org/get print(r.text) # result: # { # "args": {}, # "headers": { # "Accept": "*/*", # "Accept-Encoding": "gzip, deflate", # "Connection": "close", # "Host": "httpbin.org", # "User-Agent": "python-requests/2.19.1" # }, # "origin": "1.203.183.95", # "url": "http://httpbin.org/get" # }

2|12verify

当https网站,且此网站证书没有被官方CA机构信任,会出现证书验证错误的结果(您的链接不是私密链接)

开关, 用于认证SSL证书, 默认为True。(之前12306网站不是CA机构信任的。现在应该试了。)

## request(method, url, **kwargs),当 **kwargs 为 verify,SSL证书验证 import requests r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=True) print(r.text) r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=False) print(r.text) r = requests.request('GET', 'https://github.com', verify=True) print(r.text)

2|13cert

  当然,我们也可以制定一个本地证书用作客户端证书,这可以是单个文件(包含秘钥和证书)或一个包含两个文件路径的元组:

import requests response = requests.get("https://www.12306.cn",cert=("/path/server.crt","./path/key")) print(response.status_code)

2|14allow_redirects

开关, 表示是否允许对url进行重定向, 默认为True。

  allow_redirects=False的意义为拒绝默认的301/302/303重定向从而可以通过response.headers['Location']拿到重定向的URL。

 

2|15stream

开关, 指是否对获取内容进行立即下载, 默认为True。

2|16 

3|0requests.get(url, params=None, **kwargs)

# 官方文档 def get(url, params=None, **kwargs): kwargs.setdefault('allow_redirects', True) return request('get', url, params=params, **kwargs)

3|1requests.post(url, data=None, json=None, **kwargs)

# 官方文档 def post(url, data=None, json=None, **kwargs): return request('post', url, data=data, json=json, **kwargs)

3|2requests.head(url, **kwargs)

# 官方文档 def head(url, **kwargs): kwargs.setdefault('allow_redirects', False) return request('head', url, **kwargs)

3|3requests.options(url, **kwargs)

# 官方文档 def options(url, **kwargs): kwargs.setdefault('allow_redirects', True) return request('options', url, **kwargs)

3|4requests.put(url, data=None, **kwargs)

# 官方文档 def put(url, data=None, **kwargs): return request('put', url, data=data, **kwargs)

3|5requests.patch(url, data=None, **kwargs)

# 官方文档 def patch(url, data=None, **kwargs): return request('patch', url, data=data, **kwargs)

requests.patch和request.put类似。
两者不同的是: 当我们用patch时仅需要提交需要修改的字段。
而用put时,必须将所有字段一起提交到url,未提交字段将会被删除。
patch的好处是:节省网络带宽。

3|6requests.delete(url, **kwargs)

# 官方文档 def delete(url, **kwargs): return request('delete', url, **kwargs)

3|7requests库的异常

注意requests库有时会产生异常,比如网络连接错误、http错误异常、重定向异常、请求url超时异常等等。所以我们需要判断r.status_codes是否是200,在这里我们怎么样去捕捉异常呢?
这里我们可以利用r.raise_for_status() 语句去捕捉异常,该语句在方法内部判断r.status_code是否等于200,如果不等于,则抛出异常。
于是在这里我们有一个爬取网页的通用代码框架

try: r = requests.get(url, timeout=30) # 请求超时时间为30秒 r.raise_for_status() # 如果状态不是200,则引发异常 r.encoding = r.apparent_encoding # 配置编码 print(r.text) except: print("产生异常")

4|0二、返回数据

4|12.1 内置状态码查询对象 requests.codes

具体状态码临时百度,比如200是ok,404是not_found等

import requests r = requests.get("http://baidu.com") exit() if not r.status_code == requests.codes.ok else print("Successfully")

 

4|22.2 content返回二进制抓取图片、文件

import requests r = requests.get("https://github.com/favicon.ico") with open("facivon.ico","wb") as f: f.write(r.content)

4|3 

 

5|0三、requests的综合小实例

5|1实例一:京东商品信息的爬取

## 京东商品信息的爬取 # 不需要对头部做任何修改,即可爬网页 import requests url = 'http://item.jd.com/2967929.html' try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[:1000]) # 部分信息 except: print("失败")

 

5|2实例二:亚马逊商品信息的爬取

## 亚马逊商品信息的爬取 # 该网页中对爬虫进行的爬取做了限制,因此我们需要伪装自己为浏览器发出的请求 import requests url = 'http://www.amazon.cn/gp/product/B01M8L5Z3Y' try: kv = {'user_agent': 'Mozilla/5.0'} r = requests.get(url, headers=kv) # 改变自己的请求数据 r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[1000:2000]) # 部分信息 except: print("失败")

5|3实例三:百度搜索关键字提交

## 百度搜索关键字提交 # 百度的关键字接口:https://www.baidu.com/s?wd=keyword import requests keyword = 'python' try: kv = {'wd': keyword} headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"} r = requests.get('https://www.baidu.com/s', params=kv, headers=headers) r.raise_for_status() r.encoding = r.apparent_encoding # print(len(r.text)) print(r.text) except: print("失败")

5|4实例四:网络图片的爬取

## 网络图片的爬取 import requests import os try: url = "https://odonohz90.qnssl.com/library/145456/bb0b3faa7a872d012bb4c57256b47585.jpg?imageView2/2/w/1000/h/1000/q/75" # 图片地址 root = r"D:\DataguruPyhton\PythonSpider\lesson3\pic\\" path = root + url.split("/")[-1] if not path.endswith(".jpg"): path += ".jpg" if not os.path.exists(root): # 目录不存在创建目录 os.mkdir(root) if not os.path.exists(path): # 文件不存在则下载 r = requests.get(url) f = open(path, "wb") f.write(r.content) f.close() print("文件下载成功") else: print("文件已经存在") except: print("获取失败")

 





__EOF__

本文作者😎
本文链接https://www.cnblogs.com/dongye95/p/10943304.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   dongye95  阅读(521)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2018-05-29 一 网络基础之网络协议篇
点击右上角即可分享
微信分享提示