使用urllib库有不少不便之处,如处理网页验证和Cookies时,须要写Opener和Handler来处理,为了更方便地实现这些操做,就须要使用到requestsgit
urllib库的urlopen()方法其实是以GET方式请求网页,而requests中相应的方法就是get()方法github
import requests r=requests.get('https://www.baidu.com/') print(type(r)) print(r.status_code) print(type(r.text)) print(r.text) print(r.cookies)
其还能够用post(),put(),delete()等方法实现POST,PUT,DELETE等请求正则表达式
import requests r=requests.get('http://httpbin.org/get') print(r.text)
请求的连接是http://httpbin.org/get,该网站会判断若是客户端发起的是GET请求的话,它返回相应的请求信息,返回的结果中包含请求头,URL,IP等信息json
对于GET请求若是要添加参数,使用params这个参数就能够了浏览器
import requests data={ 'name':'dengwenxiong', 'age':23 } r=requests.get('http://httpbin.org/get',params=data) print(r.text)
另外,网页的返回类型其实是str类型,可是它很特殊,是JSON格式的,因此想直接解析返回结果,获得一个字典格式的话,能够直接调用json()方法服务器
import requests r=requests.get("http://httpbin.org/get") print(type(r.text)) print(r.json()) print(type(r.json()))
A.抓取网页cookie
请求普通的网页网络
import requests import re headers={ 'User-Agent': 'Mozilla/5.0(Macintosh;Inter Mac OS X 10_11_4) AppleWebKit/537.36(KHTML.like Gecko) Chrome/52.0.2743.116 Safari/537.36 ' } r=requests.get("https://www.zhihu.com/explore",headers=headers) pattern=re.compile('explore-feed.*?question_link.*?>(.*?)</a>',re.S) title=re.findall(pattern,r.text) print(title)
这里加入了headers信息,其中包含了User-Agent字段信息,即浏览器标识信息,不加入这个知乎就会禁止爬取,而后用正则表达式匹配出问题的内容数据结构
B.抓取二进制数据post
图片,音频,视频这些文件本质上都是由二进制码组成,想要抓取他们,就要拿到它们的二进制码
import requests r=requests.get('https://github.com/favicon.ico') print(r.text) print(r.content)
这里抓取的内容是Github的站点图标,因为图片是二进制数据,因此前者在打印时转化为str类型,即图片直接转化为字符串,因此出现乱码;后者是bytes类型的数据
将提取的图片保存下来
import requests r=requests.get("https://github.com/favicon.ico") with open("favicon.ico",'wb') as f: f.write(r.content)
音频视频也能够用这种方法获取
import requests data={'name':'dengwenxiong', 'age':23} r=requests.post("http://httpbin.org/post",data=data) print(r.text)
import requests r=requests.get("http://www.jianshu.com") 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)
获得的响应不只可使用text和content获取响应的内容,还可使用status_code属性获取状态码,使用headers属性获取响应头,使用cookies属性获取cookies,使用url属性获取url,使用history属性获取请求历史
还有内置的状态码查询对象requests.codes
import requests files={'file':open('favicon.ico','rb')} r=requests.post("http://httpbin.org/post",files=files) print(r.text)
文件上传部分会单独有一个files字段来标识
获取cookies的代码
import requests r=requests.get("https://www.baidu.com") print(r.cookies) for key,value in r.cookies.items(): print(key+'='+value)
这里首先调用cookies属性获得Cookies,其是一个RequestCookieJar类型,而后用items()方法将其转化为元组组成的列表,遍历输出每个cookie的名称和值,实现Cookie的遍历解析
在requests中,若是直接利用get()或post()等方法能够作到模拟网页请求,但这其实是至关于两个不一样的会话,及至关于用了两个浏览器打开了不一样的页面;要解决这个问题的主要方法是维持同一个会话,及至关于打开一个新的浏览器选项卡而不是新开一个浏览器,这时就要用到Session对象,利用它,能够很方便地维持一个会话,不用担忧cookies问题,它会自动帮咱们处理好。
示例以下:
import requests requests.get("http://httpbin.org/cookies/set/number/123456789") r=requests.get("http://httpbin.org/cookies") print(r.text)
请求了http://httpbin.org/cookies/set/number/123456789,请求这个网址时,能够设置一个cookies,名称叫做number。内容是123456789,随后又请求了http://httpbin.org/cookies此网址能够获取当前的Cookies
结果并不行
import requests s=requests.Session() s.get("http://httpbin.org/cookies/set/number/123456789") r=s.get("http://httpbin.org/cookies") print(r.text)
这样就能成功获取。
requests提供了证书验证的功能;当发送HTTP请求时,它会检查SSL证书,咱们可使用verify参数控制是否检查此证书,若是不加verify参数的话,默认时True,会自动验证
import requests from requests.packages import urllib3 urllib3.disable_warnings()#忽略警告 response=requests.get("https://www.12306.cn",verify=False)#设置不验证证书 print(resposne.status_code)
#经过捕获警告到日志的方式忽略警告
import requests import logging logging.captureWarnings(True) response=requests.get("https://www.12306.cn",verify=False) print(response.status_code)
也能够指定一个本地证书用做客户端证书,这里能够是单个文件(包含证书和密钥)或一个包含两个文件路径的元组:
import reqeusts response=requests.get("https://www.12306.cn",cert=("/path/server.crt","/path/key")) print(response.status_code)
对于某些网站,在测试的时候请求几回能正常获取内容,但一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登陆认证页面,更有可能会直接封禁客户端IP,致使必定时间段内没法访问。
为了防止这种状况发生,咱们须要设置代理来解决这个问题,这就须要用到proxies 参数
import requests proxies={ "http":"http://10.10.1.10:3128", “https”:"https://10.10.1.10:1080" } requests.get("https://www.taobao.com",proxies=proxies)
若代理须要使用HTTP Basic Auth,可使用相似http://user:password@host:port这样的语法来设置代理
import requests proxies={ "http":"http://user:password@10.10.1.10:3128", } requests.get("https://www.taobao.com",proxies=proxies)
除了最基本的HTTP代理外,requests还支持SOCKS协议的代理,首先要安装socks这个库,而后就可使用SOCKS协议代理了
import requests proxies={ "http":"sock5://user:password@host:port" "https":"sock5://user:password@host:port" } requests.get("https://www.taobao.com",proxies=proxies)
在本机网络状况很差或者服务器网络响应太慢甚至无响应时,咱们可能会等待特别久的时间才能收到响应,甚至到最后收不到响应而报错,为了防止服务器不能及时响应,应该设置一个超时时间,即超过这个时间还没获得响应那就报错,这就须要用到timeout参数,这个时间是发出请求到服务器返回响应的时间
import requests response=requests.get('https://www.taobao.com',timeout=1) print(response.status_code)
实际上,请求分为两个阶段,链接(connect)和读取(read)
timeout能够指定两者的总和,也能够传入一个元组分别指定
request.get("https://www.taobao.com",timeout=(5,11,30))
若是向=想永久等待,能够直接将timeout设置为None,或者不设置直接留空
在访问网站时,可能会遇到须要认证的网页,这时可使用requests自带的身份认证功能
import requests from requests.auth import HTTPBasicAuth r=requests.get("http://localhost:5000",auth=HTTPBasicAuth('username','password')) print(r.status_code)
若是直接传一个元组,它会默认使用HTTPBasicAuth这个类来认证
因此上面代码简写为
import requests r=requests.get("http://localhost:5000",auth=('username','password')) print(r.status_code)
前面介绍urllib时,咱们能够将请求表示为数据结构,其中各个参数均可以经过一个Request对象来表示;这在requests一样能够作到,这个数据结构就叫Prepared Request
from requests import Request,Session url="http://httpbin.org/post" data={ 'name':'dengwenxiong' } headers={ 'User-agent':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/53.0.2785.116 Safari/537.36' } s=Session() req=Request("POST",url,data=data,headers=headers) prepped=s.prepare_request(req) r=s.send(prepped) print(r.text)
这里引入了Request,而后用url,data和headers参数构造了一个Request对象,这时须要再调用Session的prepare_request()方法将其转换为一个Prepared Request对象,而后调用send()方法便可