基本用法
import requests
#请求网页地址
r = requests.get("https://www.baidu.com/")
#打印请求网站返回的类型
print(type(r))
#打印状态码
print(r.status_code)
#打印网站以text格式返回的类型
print(type(r.text))
#打印网站以text返回的内容
print(r.text)
#打印请求网站的cookies
print(r.cookies)
这里我们调用get()方法,得到一个 Response,然后分别输出了Respouse的类型,状态码、响应体的类型、内容以及Cookies。
通过运行结果发现,它的返回类型是requests.models.Response响应体的类型是字符串str,Cookies的类型是RequestsCookiejar。
除了get()方法外还有其他方法:
r = requests.post("https://www.baidu.com/")
r = requests.put("https://www.baidu.com/")
r = requests.delete("https://www.baidu.com/")
r = requests.head("https://www.baidu.com/")
r = requests.options("https://www.baidu.com/")
GET请求
import requests
#普通请求方式
#返回的是字符串类型
r =requests.get("http://httpbin.org/get")
print(type(r.text))
print(r.text)
#带参数请求方式
data = {
'name':'germey',
'age':22,
}
r = requests.get('http://httpbin.org/get',params=data)
print(r.text)
#将返回结果是json格式的字符串转换成字典。
# 但是需要注意的是,如果返回结果不是json格式,用json()转换会抛出json.decoder.JSONDecodeError异常
r =requests.get("http://httpbin.org/get")
print(type(r.json()))
print(r.json())
示例:抓取网页
import requests
import re
'''抓取网页内容'''
#设置请求头信息,因为这里请求的是知乎,所有得加上浏览器信息,不然知乎不让请求
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0'
}
#请求网站的地址
r = requests.get("https://www.zhihu.com/explore",headers=headers)
#通过正则匹配要抓取的数据
pattern = re.compile('explore-feed.*?question_link.*?>(.*?)', re.S)
#把匹配到的内容打印出来
titles = re.findall(pattern, r.text)
print(titles)
'''抓取网页图片(二进制数据)'''
r = requests.get("https://github.com/favicon.ico")
#以二进制形式打开文件
with open('favicon.ico','wb')as f:
#content以二进制的字节码类型返回数据
#把返回的二进制数据写入到上一步打开的文件中
f.write(r.content)
POST请求
import requests
data = {
'name':'germey',
'age':22,
}
r = requests.post("http://httpbin.org/post",data=data)
print(r.text)
#可以看到form部分就是提交的数据
响应
import requests
'''响应的内容'''
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36'
}
r = requests.get('https://www.jianshu.com/',headers=headers)
print('#打印响应的状态码类型和状态码')
print(type(r.status_code), r.status_code)
print('#打印响应头的类型和响应头信息')
print(type(r.headers), r.headers)
print('#打印响应cookies类型和cookies')
print(type(r.cookies), r.cookies)
print('#打印url类型和url地址')
print(type(r.url), r.url)
print('#打印请求历史')
print(type(r.history) ,r.history)
#requests内置的状态码查询对象requests.codes
if r.status_code != requests.codes.ok:#ok代表200
print('失败')
else:
print('request Successfully')
上传文件
import requests
#上传文件用files字段来标识
# open('文件路径','打开模式')
files = {'file':open('favicon.ico','rb')}
r = requests.post("http://httpbin.org/post",files=files)
print(r.text)
下载文件
import requests
url = "下载地址"
r = requests.get(url)
with open("/保存路径/文件名称.后缀", "wb") as f:
f.write(r.content)
Cookies
import requests
#请求百度网址
r = requests.get("https://www.baidu.com")
#打印返回的cookies信息
print(r.cookies)
#获取到cookiess是个RequestsCookieJar类型的对象
#然后用items()方法将其转换为元组组成的列表,遍历输出每一个cookies的名称和值
for key, valuein r.cookies.items():
print(key +"=" + value)
使用cookie来维持登录状态
#首先登录知乎将headers中的cookies内容复制下来
headers = {
'Cookie':'d_c0="AKBjQEMmqA2PTpAQRZh7rw7gPp6JAWLHqlE=|1527402618"; q_c1=a48b22bfb7dc41aca7d65b5b2c776785|1527402618000|1527402618000; _zap=2d294c07-33a4-4858-93d2-7645340a7a05; l_cap_id="ZGExMjNjYzgzYTE5NGIzNmI0N2U0MzQ0OGEwOTJlNTg=|1527402644|701269f45562c2dc85e05b5dbf175ca233393647"; r_cap_id="ZGU5NzY5ZWFiZWQ5NDY5YWJmNTZkY2ZkZWViNjRjM2E=|1527402644|5d4a1ca33a036dca76f7ba7bec4425d3addc90c4"; cap_id="NmUyZDY1MjJiY2NlNDkzYjhhMjhkOTc5YjIwZmYxOWY=|1527402644|8680a5ccf77719a30955cabc930f579a0adedb49"; tgw_l7_route=860ecf76daf7b83f5a2f2dc22dccf049; _xsrf=adb18f22-cccd-406d-8a1a-abdfd837b932; capsion_ticket="2|1:0|10:1527519783|14:capsion_ticket|44:MTNiMDZhMDdlZDY3NGQ5N2FiM2YwOTZmNTBlOGZkZWU=|2658391dfc3c1fff6d7f3f17ebf2f406fd7434d06c5828d1b9ccf570de54f978"; z_c0="2|1:0|10:1527519820|4:z_c0|92:Mi4xMnBZUEJBQUFBQUFBb0dOQVF5YW9EU1lBQUFCZ0FsVk5UR2o1V3dDbm1oOFBRcGJfNjl5YmRielBqOG92ZUJjWVJB|f0b771ac073a4a9cfaa1d7c738ab08168de64eb1419da1742bb8120dab4940f4"',
'Host':'www.zhihu.com',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
}
r = requests.get('https://www.zhihu.com',headers=headers)
print(r.text)
通过cookies参数来设置
这里我们首先新建一个RequestsCookieJar对象,然后将复制下来的cookies利用split()方法分割,
接着利用set()方法设置好每个cookie的key和value,然后通过调用request的get()方法并传递
给cookies参数即可,由于知乎本身的限制,headers参数也不能少。
测试后,发现同样可以正常登陆知乎。'''
cookies ='d_c0="AKBjQEMmqA2PTpAQRZh7rw7gPp6JAWLHqlE=|1527402618"; q_c1=a48b22bfb7dc41aca7d65b5b2c776785|1527402618000|1527402618000; _zap=2d294c07-33a4-4858-93d2-7645340a7a05; l_cap_id="ZGExMjNjYzgzYTE5NGIzNmI0N2U0MzQ0OGEwOTJlNTg=|1527402644|701269f45562c2dc85e05b5dbf175ca233393647"; r_cap_id="ZGU5NzY5ZWFiZWQ5NDY5YWJmNTZkY2ZkZWViNjRjM2E=|1527402644|5d4a1ca33a036dca76f7ba7bec4425d3addc90c4"; cap_id="NmUyZDY1MjJiY2NlNDkzYjhhMjhkOTc5YjIwZmYxOWY=|1527402644|8680a5ccf77719a30955cabc930f579a0adedb49"; tgw_l7_route=860ecf76daf7b83f5a2f2dc22dccf049; _xsrf=adb18f22-cccd-406d-8a1a-abdfd837b932; capsion_ticket="2|1:0|10:1527519783|14:capsion_ticket|44:MTNiMDZhMDdlZDY3NGQ5N2FiM2YwOTZmNTBlOGZkZWU=|2658391dfc3c1fff6d7f3f17ebf2f406fd7434d06c5828d1b9ccf570de54f978"; z_c0="2|1:0|10:1527519820|4:z_c0|92:Mi4xMnBZUEJBQUFBQUFBb0dOQVF5YW9EU1lBQUFCZ0FsVk5UR2o1V3dDbm1oOFBRcGJfNjl5YmRielBqOG92ZUJjWVJB|f0b771ac073a4a9cfaa1d7c738ab08168de64eb1419da1742bb8120dab4940f4"'
#构造RequestsCookieJar对象
jar = requests.cookies.RequestsCookieJar()
#设置头信息需要告诉服务器使用浏览器版本否则服务器禁止使用request访问
headers = {
'Host':'www.zhihu.com',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
}
for cookie in cookies.split(';'):
#split分割
#第一个参数:可选参数,指定的分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
#第二个参数:可选参数,分割次数,默认为分隔符在字符串中出现的总次数。
key, value = cookie.split('=',1)
#把获取到的cookie的key和value添加到构造出来RequestsCookieJar对象
jar.set(key, value)
#把已经获取到的cookie传给cookies参数
r = requests.get('https://www.zhihu.com',cookies=jar,headers=headers)
print(r.text)
会话维持Session
利用Session,可以做到模拟同一个会话而不用担心Cookies的问题。它通常用于模拟登陆成功之后在进行下一步的操作。
设想这样一个场景,第一个请求利用Post()方法登陆了某个网站,第二次想获取成功登陆后的个人信息,你又用了一次get()方法
去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的会话,能成功获取个人信息吗?当然是不能。
impost requests
s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/12345678') # 第一次模拟登陆
r = s.get('http://httpbin.org/coolies') # 第二次登陆后的操作
prionrt(r.text)
SSL证书验证
import requests
'''如果请求一个HTTPS站点,但是证书验证错误的页面时,就会报SSLError错误,
那么如何避免这个错误呢?很简单,把verify参数设置为False即可(默认为True)'''
response = requests.get('https://www.12306.cn',verify=False)
print(response.status_code)
print("============这是一条分割线1============")
# 不过我们发现一个警告:InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised.
# 它建议我们给它指定证书,我们可以通过设置忽略警告的方式来屏蔽这个警告
import urllib3
urllib3.disable_warnings()
response = requests.get('https://www.12306.cn',verify=False)
print(response.status_code)
print("============这是一条分割线2============")
#或者通过捕获警告到日志的方式忽略警告
import logging
logging.captureWarnings(True)
response = requests.get('https://www.12306.cn',verify=False)
print(response.status_code)
print("============这是一条分割线3============")
#当然也可以指定一个本地证书用做客户端证书,这可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组
#下面的代码是演示实例,我们需要有crt和key文件,并且指定他们的路径。注意本地私有证书的key必须是解密状态,加密状态的key是不支持的
#response = requests.get('https://www.12306.cn', cert=('/path/server.crt', '/path/key'))
#print(response.status_code)
代理设置
对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,
网站可能会弹出验证码,或者跳转到登陆验证页面,更甚者可能会直接封禁IP,这时候需要设置代理来解决这个问题了。
import requests
#设置HTTP代理Ip
proxies = {
'http':'http://127.0.0.1:1185',
'https':'http://127.0.0.1:1185',
}
r = requests.get('https://www.taobao.com',proxies=proxies)
print(r.status_code)
print("============这是一条分割线1============")
# 若代理需要使用HTTP Basic Auth,可以使用类似http://user:password@host:port这样的语法来设置代理
proxies = {
"http":"http://user:password@10.10.1.10:3128/"
}
r = requests.get('https://www.taobao.com',proxies=proxies)
print(r.status_code)
#使用SOCKS协议代理
proxies = {
'http':'socks5://127.0.0.1:1188',
'https':'socks5://127.0.0.1:1188',
}
r = requests.get('https://www.taobao.com',proxies=proxies)
print(r.status_code)
当然,直接运行这个实例可能不行,因为这些代理都是无效的,请换成自己的有效代理实验。
超时设置
import requests
'''
设置超时时间。
如果超过了这个时间还没有得到相应,就报错'''
#设置超时时间为1秒,如果1秒内没有响应,那就抛出异常。
r = requests.get("http://www.taobao.com",timeout=1)
print(r.status_code)
#实际上请求分为两个阶段,即连接和读取,上面设置timeout=1将用作连接和读取这二者的timeout的总和。
#如果分别指定,可以传入一个元组
r = requests.get("http://www.taobao.com",timeout=(5,11))
print(r.status_code)
#如果想永久等待,可以直接将timeout设置为None
r = requests.get("http://www.taobao.com",timeout=None)
print(r.status_code)
#或者不加参数
r = requests.get("http://www.taobao.com")
print(r.status_code)
身份认证
import requests
'''
身份认证:
如果用户密码认证成功,会返回200状态码;如果认证失败,则返回401状态码'''
#auth=传送的是个元组
#r = requests.get('http://localhost:5000', auth=('username', 'password'))
#print(r.status_code)
'''
requests还提供了其他认证方式,如OAuth认证,不过需要安装oauth包pip install requests_oauthlib
'''
from requests_oauthlibimport OAuth1
url ='https://api.twitter.com/1.1/account/verify_credentials.json'
auth = OAuth1('YOUR_APP_KEY','YOUR_APP_SECRET','USER_OAUTH_TOKEN','USER_OAUTH_TOKEN_SECRET')
r = requests.get(url,auth=auth)
print(r.status_code)
更多详细功能可以参考:IT虾米网
Prepared Request
from requestsimport Request, Session
'''
前面我们都是用requests方法请求
其实也可以自己构造请求数据结构
如下:'''
#请求的URL地址
url ='http://httpbin.org/post'
#post请求数据
data = {
'name':'germey'
}
#请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0'
}
#实例化session对象
s = Session()
#把构造的请求数据传给Request对象并附值给req
req = Request('POST', url,data=data,headers=headers)
#把req传送给Session对象内的prepare_request方法
prepped = s.prepare_request(req)
#使用send请求
r = s.send(prepped)
print(r.text)
# 可以看到,我们达到了同样的POST请求效果。
更多的用法可以参考requests的官方文档:IT虾米网