python网络爬虫之二requests模块

蓝咒 提交于 2020-03-25 15:11:21
requests http请求库
requests是基于python内置的urllib3来编写的,它比urllib更加方便,特别是在添加headers,
post请求,以及cookies的设置上,处理代理请求,用几句话就可以实现,而urllib比较繁琐,
requests比urllib方便多了,requests是一个简单易用的http请求库。

官方网站是:
简单实例:
import requests 
response = requests.get("https://www.baidu.com/")
print(type(response))
print(response.status_code)
print(type(response.text))
print(response.text)
print(response.cookies)

这样我们就很方便的把请求的cookies获取出来了。

各种请求方式:
import requests
requests.get("http://httpbin.org/get")
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")


一.基本的GET请求
1. 基本的http get请求:
import requests
response = requests.get("http://httpbin.org/get")
print(response.text)
我们可以通过response.text获取请求内容。

2. 带参数的get请求
import requests
response = requests.get("http://httpbin.org/get?name=germey&age=22")
print(response.text)
带参数请求:我们只需在链接地址后面加问好?然后后面带参数的名和值,参数和参数
之间用与&隔开。
另外requests函数也提供了一个params参数,可以代表用户向浏览器的请求,这样我们
就可以使用json字典的形式传递参数:
如:
格式如下:
response = requests.get(url,params=data)

import requests
data = {
    "name":"germey",
    "age":22
}
response = requests.get("http://httpbin.org/get",params=data)
print(response.text)

3. 解析成json格式数据,这样方式在ajax请求的时候非常常用。
import requests
import json
response = requests.get("http://httpbin.org/get")
print(type(response))            #是一个class返回对象<class 'requests.models.Response'>
print(type(response.text))       #是一个字符串文本对象<class 'str'>
print(response.text)             #是一个字符串文本
print(type(response.json()))     #是一个json字典对象<class 'dict'>
print(response.json())           #是一个json字典文本,数据与下面相同
print(json.loads(response.text)) #是一个json字典文本,数据与上面相同
#而json.loads实际上是对返回的字符串对象进行一个json序列化操作,
#实际上json.loads(response.text)=response.json()


4. 获取二进制数据
是指下载文本数据,图片,视频时的下载对象,此时需要将文本,图片,视频等数据转换
成二进制数据,然后再将文本,图片,视频等数据保存到文件,此时我们就可以得到我们
想要的文本,图片和视频等数据了。
import requests
response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
print(type(response.text))           #是一个字符串文本对象<class 'str'>
print(type(response.content))        #是一个bytes字节码对象<class 'bytes'>
print(response.text)                 #是一个string格式的乱码字符串
print(response.content)              #是一个字节码的bytes字节流

#下载文本,图片,或者视频的方法:
import requests
response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
with open("1.jpg","wb") as f:
    f.write(response.content)
f.close()
#经过上面的验证,此时我们就可以根据以上方法获取文件,图片,或视频的的文件。此时我们需要
#将文件,图片,或视频链接地址传进去,然后将获取的文件,图片,或视频一字节流的形式写入到
#文件,此时我们打开文件,就可以获取到我们想要的文本,图片,或视频的的文件

#通过以上我们可以得出结论,如果获取字符串或者是二进制字节流信息,我们字节可以调用text或者
#content方法,但是如果我们想要获取json格式的字典数据,后面还得加一个括号,因为json不是原生
#自动转过来的,而是可以看成根据text文件二次转过来的。


5. 添加headers
添加headers是非常重要的,有时候我们在使用爬虫获取数据的时候,如果不添加headers,服务可能会
直接把我们禁掉,或者是服务器出出现请求或者回复错误等响应,我们以爬取知乎网站为例,如果我们
不添加headers,那么服务器会返回一个500状态码等一个这样的错误,如:
import requests
response = requests.get("https://www.zhihu.com/")
print(response.text)
此时会提示500错误。

添加浏览器的headers,其实就是伪装成一个浏览器。
import requests
headers = {
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
response = requests.get("https://www.zhihu.com/",headers=headers)
print(response.text)

关于headers内部的参数,我们可以从一个浏览器里面提取,在浏览器里面的请求参数中的:
user-agent字段,即代表了我们请求服务器所用的浏览器客户端信息,此时我们将他复制下来,
添加到headers字典中即可。

二.POST请求

1.基本的post请求:
post是将数据以form表单的形式传给服务器,此时我们需要以一个data数据字典的形式作为数据传递过去,
例如:
import requests
data = {"name":"germey","age":"22"}
response = requests.post("http://httpbin.org/post",data=data)
print(response.text)


2. post请求添加headers:
import requests
data = {"name":"germey","age":"22"}
headers = {
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
response = requests.post("http://httpbin.org/post",data=data,headers=headers)
print(response.text)
print(response.json())

三.返回的response属性:
import requests
response = requests.get("http://www.baidu.com/")
print(type(response.status_code),response.status_code)            
print(type(response.headers),response.headers)       
print(type(response.cookies),response.cookies)             
print(type(response.url),response.url)     
print(type(response.history),response.history)

response回复带有很多属性,常用的属性有:
1. 状态码: response.status_code   int类型
2. headers:response.headers       字典类型
3. cookies: response.cookies       cookies类型
4. url:     response.url           这个url就是我们请求的url          
5. history: response.history       list元组类型,我们访问的历史记录

1. 状态码的判断,我们的浏览器都有一个状态码的分组,我们可以给根据这个状态码来进行一些
判断:
常见的有:
#请求成功的状态码:
100  状态码的名字
200  状态码的名字是ok
#redirect error:
300
#client error:
400
#server error:
500
另外每一个状态码都有一个自己的名字,我们也可以调用这个状态码的名字来进行判断,而不用记住
特定的状态码了,例如200的状态码是ok,此时我们就可以通过以下两种方式来验证判断。
第一种方式,通过状态码来进行验证:
即验证:if response.status_code == 状态码
import requests
response = requests.get("http://www.baidu.com/")
exit() if not response.status_code == 200 else print("Request Successfully")
此时打印:
Request Successfully
第一种方式,通过状态码的名字来进行验证:
即验证:if response.status_code == requests.codes.状态码的名字(即请求状态码的名字)。
import requests
response = requests.get("http://www.baidu.com/")
exit() if not response.status_code == requests.codes.ok else print("Request Successfully")
此时打印:if response.status_code == 状态码
Request Successfully

四.requests的其他的一些高级操作

1.文件上传
import requests
files = {'file':open("1.jpg","rb")}   #在这指定上传后的文件名,我们也可以指定其他名字。
response = requests.post("http://httpbin.org/post",files=files)
print(response.text)

2.获取cookies
我们可以直接通过response.cookies这个属性,就可把cookies获取打印出来了,这个cookies实际上
是一个列表的形式,因此可以表示成这种形式:response.cookies.items(),这样我们就可以通过
for循环的形式把这些cookies打印出来,他们都是一个个key-value结构形式的数据。
import requests
response = requests.get("https://www.baidu.com/")
print(response.cookies)
for key,value in response.cookies.items():
    print(key + 'n' + value)

3.会话维持
cookies是做会话维持的,有了这个cookies,我们就可以模拟一个用户一直维持在一个登陆状态,相当于
一个用户在一个浏览器里面一直维持登陆状态的操作。
import requests 
requests.get("http://httpbin.org/cookies/set/number/123456789")  #先为这个网站设置一个cookies
response = requests.get("http://httpbin.org/cookies")            #然后我们就可以把当前的这个网站的cookies拿到
print(response.text)
此时我们打印:
{
  "cookies": {}
}
#通过上面可以看到,我们获取的cookies是0,没有,其实根本原因也就是上面我们发起的两次请求
#分别是两个独立的过程,我们可以理解为,我们用一个浏览器设置了一个cookies,然后再用另外一个
#浏览器访问,也就是这个两个请求是独立的,此时我们需要模拟在一个浏览器里面操作,模拟一个set
#和get cookies的操作,此时就得用到如下方法。

requests提供了一个Session的对象,我们可以通过声明一个Session的对象,然后再用这个Session对象
发起两次get请求,那么这两次请求就相当于在一个浏览器里面操作了。
import requests 
s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123456789")
response = s.get("http://httpbin.org/cookies")
print(response.text)
此时打印:
{
  "cookies": {
    "number": "123456789"
  }
}
#这个方法非常常用,假如我们再做模拟登录验证的时候,可以创建这么一个session对象,
#然后用这个session post一下用户名和密码,这样我们就相当于登录了,然后我们再用这个
#session对象进行操作,此时我们就会维持这么一个登录信息,我们就相当于再登录状态下操作
#了,此时我们就可以获取一些登录后的页面了,假如我们再做模拟登录的话,我么可以使用
#requests.Session这个对象来操作。

4.证书验证
现在的很多网站都是以https格式的网站了,假如入我们查看12306的网站,此时会提示一个ssl证书错误,
因为我们的爬虫程序没有ssl证书,因此在爬取数据或者与网站交互的时候会提示ssl错误。
此时,我们假如使用requests模块请求一个https网站的时候,可以使用两种方法来处理:
第一种方式:如果网站使用了不合法的证书,比如网站自己自己创建了以个证书,此时我们可以使用一个
参数verify=False来忽略这个证书,如果是合法的证书的话,也可以使用verif=False这个参数来忽略这个
证书,但是后面也会提示
例如:直接请求12306网站:
import requests
response = requests.get("https://www.12306.cn/")
print(response.status_code)
此时会提示ssl证书错误。

我们加一个参数verify=False访问,
import requests
response = requests.get("https://www.12306.cn/",verify=False)
print(response.status_code)
此时就可以正常访问操作了。
但是此时会打印信息如下:
C:\Program Files (x86)\Python\lib\site-packages\urllib3\connectionpool.py:858: 
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification 
is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
200

从上面信息我们可以看到,虽然我们将证书验证设置为False之后,但是在输出结果还是会提示一个警告warnings
的信息,提示最好加一个证书,此时我们通过requests模块导入一个叫做urllib3的原生的包,然后通过调用这个
urllib3的一个disable_warning方法来消除这些警告信息,如from requests import urllib3,经过测试,我们也
可以直接导入这个urllib3的包。
如下所示:
import requests
import urllib3
urllib3.disable_warnings()
response = requests.get("https://www.12306.cn/",verify=False)
print(response.status_code)


第二种方式.我们可以手动使用cert参数指定一个证书的验证,此时需要添加一个cert参数,此时我们的请求就会
自动的通过这个CA证书进行验证了,如下所示:
import requests
response = requests.get("https://www.12306.con/",cert=("/path/server.crt","/path/key"))
print(response.status_code)

5.代理设置
第一种方式:http代理
我们只需设置一个proxies代理的字典,然后将这个代理传过去既可以了。
import requests
proxies = {
   "http":"http://127.0.0.1:10010",
   "https":"https://127.0.0.1:10011",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)
此时我们就可以使用我们的代理来访问网站了。
假如我们的代理需要用户名和密码,此时我们可以在代理前面添加一个用户名和密码,然后加一个
'@'符,此时我们就可以访问了,如下所示:
import requests
proxies = {
   "http":"http://user:password@127.0.0.1:10010",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)

第二种方式:使用socks代理:
此时我们需要安装一个requests[socks]模块
pip install requests[socks]
import requests
proxies = {
   "http":"socks5://127.0.0.1:10010",
   "https":"socks5://127.0.0.1:10011",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)
此时我们就可以通过socks代理来进行访问了。

6.超时的设置:
超时的设置,实际上就是设置一个timeout,假如我们在请求一个网站时,限制一个超时时间的设置,
此时我们可以设置一个timeout的参数。
如下:
import requests
response = requests.get("https://www.taobao.com/",timeout=1)
print(response.status_code)
此时能正常访问。
如果我们设置个一个较短的时间,比如0.001秒,那么他就会抛出一个
import requests
response = requests.get("https://www.taobao.com/",timeout=0.001)
print(response.status_code)
此时就会出现浏览器访问超时错误,提示抛出一个如下的ReadTimeout的异常:
#requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.taobao.com', port=443): 
#Read timed out. (read timeout=0.01)     
import requests
from requests.exceptions import ReadTimeout
try:
     response = requests.get("https://www.taobao.com/",timeout=0.01)
     print(response.status_code)
except ReadTimeout:
     print("timeout")
此时就会输出一个:
#timeout

7.认证设置
有的网站访问的时候需要输入一个用户名和密码才能登录访问,登录以后我们才能看到网站页面里
的内容,假如我们遇到这样一个需要登录验证的网站,requests模块提供了一个auth参数,我们就
可以通过这个auth传入一个HTTPBasicAuth参数把用户名和密码传过来,这样的话我们就可以正常
登录进去完成一个正常的请求。
假如我们不传入用户名和密码,直接请求:
import requests
response = requests.get("http://www.11111.com")
print(response.status_code)
此时就会返回请求被禁止的401状态码:
输入如下:
#401
此时我们可以使用auth将我们的用户名和密码传过去:
第一种方法,直接传入一个字典:
import requests
response = requests.get("http://www.11111.com",auth=('username','password'))
print(response.status_code)

第二种方法,通过HTTPBasicAuth传入一个字典,这两种方式都可以。
import requests
from requests.auth import HTTPBasicAuth
response = requests.get("http://www.11111.com",auth=HTTPBasicAuth('username','password'))
print(response.status_code)

此时就可以正常访问了。

8.关于异常处理的部分
import requests 
from requests.exceptions import ReadTimeout,HTTPError,ConnectionError,

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!