Python Requests的基本用法
requests的基本用法
1. requests介绍
Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库。requests的功能和urllib基本相同,主要是向网站发送和接受数据。与urllib相比的话,requests更加的方便
2. 安装requests
pip install requests
3. 构建GET请求
- 什么是GET请求
GET - 从指定的资源请求数据。 - 基本实现方法
我们先导入requests库,用requests.get()方法向指定的url发送GET请求,然后我们可以用text属性将响应内容以文本的方式输出 - 基本实例
import requests # 导入reques库
url = 'http://www.baidu.com' # 请求的url
response = requests.get(url) # 构建get请求方式,并获取响应
print(response.text) # 输出响应的内容(页面源代码)
- 返回的部分内容如下
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always" name="referrer"><meta name="theme-color" content="#2932e1"><link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /><link rel="search" type="application/opensearchdescription+xml" href="/content-search.xml" title="百度搜索" /><link rel="icon" sizes="any" mask
href="//www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg"><link rel="dns-prefetch" href="//s1.bdstatic.com"/><link rel="dns-prefetch" href="//t1.baidu.com"/><link rel="dns-prefetch" href="//t2.baidu.com"/><link rel="dns-prefetch" href="//t3.baidu.com"/><link rel="dns-prefetch" href="//t10.baidu.com"/><link rel="dns-prefetch" href="//t11.baidu.com"/><link rel="dns-prefetch" href="//t12.baidu.com"/><link rel="dns-prefetch" href="//b1.bdstatic.com"/><title>百度一下,你就知道</title><style type="text/css" id="css_index" index="index">
- 参数传递
在网站中GET方式提交的参数在url里面,我们可以通过修改url来修改参数,在requests库中给我们提供了更加人性化的属性,我们可以通过params来传递存储在字典中的参数和对应的值 - 基本实列
import requests
url1 = 'http://httpbin.org/get?id=1&username=admin&password=123456'
url2 = 'http://httpbin.org/get'
data = {'id': 1,
'username': 'admin',
'password': '123456'}
r1 = requests.get(url1)
r2 = requests.get(url2, params=data)
print(r1.text)
print('-----------------------------------------')
print(r2.text)
输出
{
"args": {
"id": "1",
"password": "123456",
"username": "admin"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "14.108.58.200, 14.108.58.200",
"url": "https://httpbin.org/get?id=1&username=admin&password=123456"
}
-----------------------------------------
{
"args": {
"id": "1",
"password": "123456",
"username": "admin"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "14.108.58.200, 14.108.58.200",
"url": "https://httpbin.org/get?id=1&username=admin&password=123456"
}
两种参数传递方法不同,但是作用还是一样的
3.1 编码解码
大家请求网站页面的时候,获取的响应文本可能会出现中文乱码的情况。这里我们可以用到requests库的encoding方法,将响应内容正确编码之后再以文本的方式输出。常见的编码有:utf-8,gbk
- 基本实例(未编码)
这里为了方便观察,我使用了正则表达式获取新浪网的标题
import requests # 导入reques库
import re
url = 'https://www.sina.com.cn/' # 请求的url
response = requests.get(url) # 构建get请求方式,并获取响应
pat = re.compile(r'<title>(.*?)</title>')
title = pat.findall(response.text)
print(title)
输出
['æ\x96°æµªé¦\x96页']
- 基本实例(使用编码)
这里我使用的是utf-8编码,具体情况根据网站的编码方式决定(通常在网站head标签下的meta标签某个位置)
import requests # 导入reques库
import re
url = 'https://www.sina.com.cn/' # 请求的url
response = requests.get(url) # 构建get请求方式,并获取响应
response.encoding = 'utf-8'
pat = re.compile(r'<title>(.*?)</title>')
title = pat.findall(response.text)
print(title)
输出
['新浪首页']
- 返回二进制的情况
我们可以用response.content.decode()把相应的二进制字节流转化为str类型
3.2 抓取二进制数据
之前我们用text属性返回了网页的文本信息,但是如果我们想获取的是图片、音乐、视频等文件怎么办呢?这里我们就要使用content属性来抓取二进制数据了。
- 基本实例(获取github的图标)
import requests
url = 'https://github.com/favicon.ico'
response = requests.get(url)
print(response.text) # text属性
print(response.content) # content属性
输出(部分)
�����������$$$ ������������
b'\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00 \x00(\x05\x00\x00&\x00\x00\x00 \x00\x00\x01\x00 \x00
- 保存图片
import requests
url = 'https://github.com/favicon.ico'
response = requests.get(url)
ico = response.content
with open('favicon.ico', 'wb') as f:
f.write(ico)
3.3 添加headers
headers代表着我们的请求头,一些网站做了反爬机制会坚持我们的请求头,如果发现是python自带的请求头可能就不会返回信息。因此我们要添加headers,把请求头伪装成网站允许的请求头。在python中headers要用字典形式。
- 基本实例(不用headers无法正常获取响应)
import requests
url = 'https://www.zhihu.com/explore'
response = requests.get(url)
print(response.text)
输出
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>openresty</center>
</body>
</html>
- 基本实例(使用headers)
import requests
url = 'https://www.zhihu.com/explore'
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64;rv:46.0) Gecko/20100101 Firefox/46.0'}
response = requests.get(url, headers=header) # 构造浏览器请求头,传入headers
print(response.text)
输出(部分)
<!doctype html>
<html lang="zh" data-theme="light"><head><meta charSet="utf-8"/><title data-react-helmet="true">发现 - 知乎</title><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="google-site-verification" content="FTeR0c8arOPKh8c5DYh_9uu98_zJbaWw53J-Sch9MTg"/><meta name="description" property="og:description" content="有问题,上知乎。知乎,可信赖的问答社区,以让每个人高效获得可信赖的解答为使命。知乎凭借认真、专业和友善的社区氛围,结构
化、易获得的优质内容,基于问答的内容生产方式和独特的社区机制,吸引、聚集了各行各业中大量的亲历者、内行人、领域专家、领域爱好者,将高质量的内容透过人的节点
来成规模地生产和分享。用户通过问答等交流方式建立信任和连接,打造和提升个人影响力,并发现、获得新机会。"/>
4. POST请求
- 什么是POST请求
POST - 向指定的资源提交要被处理的数据 - 基本实现方法
在reques中POST请求实现的方法和GET请求类似,我们可以用requests.post('your-url', data=datas)来实现POST请求,url是我们需要请求的链接,datas我们需要POST发过去的参数和参数的值。注意datas是字典。 - 基本实列
import requests
url = 'http://httpbin.org/post'
datas = {'value1': '123', 'value2': 'abc'}
response = requests.post(url, data=datas) # 构造POST请求
print(response.text)
输出
{
"args": {},
"data": "",
"files": {},
"form": {
"value1": "123",
"value2": "abc"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "21",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"json": null,
"origin": "14.108.173.81, 14.108.173.81",
"url": "https://httpbin.org/post"
}
(该网站会判断客户端发起的请求,并返回相应的请求信息,可以看到返回的响应中有我们的请求信息,所以我们这次POST请求成功)
5. 响应
爬虫就是一个发送请求获取服务器响应的过程,在上面的基本实例中我们使用text和content获取了响应的内容。此外我们还有很多属性和方法来获取其他信息,比如状态码、响应头、Cookies等等
- 基本实例(用status_code获取状态码)
import requests
url = 'http://httpbin.org/post'
datas = {'value1': '123', 'value2': 'abc'}
response = requests.post(url, data=datas)
print(response.status_code)
输出
200
状态码200表示请求成功,常用的http状态码还有400、403、404、500等等请大家自行百度,记住几个常用状态码的含义。状态码详解
- 其他属性
在基本实例中我们使用了status_code属性输出了响应的状态码,同样的方法我们可以用headers属性获取响应头,用cookies属性获取存储的Cookie信息 - 基本实例
import requests
url = 'http://httpbin.org/post'
datas = {'value1': '123', 'value2': 'abc'}
response = requests.post(url, data=datas)
print(response.headers) # 获取响应头
print(response.cookies) # 获取cookie信息
输出
{'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Fri, 17 Jan 2020 01:55:43 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options':
'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '272', 'Connection': 'keep-alive'}
<RequestsCookieJar[]>
6. Cookie
Cookie大家可以简单的理解为一种登录凭证,在一般情况下拿到Cookie我们可以不用输入账号密码,只需要Cookie便可以登录成功。上面我们介绍了如何获取响应中的Cookie,这里我给大家简单的说一下如何发送Cooike
- 基本实现方法
在浏览器中我们可以看到Cookie是通过请求头向网站的服务器发送的,在requests中我们之前介绍了请求头headers,因此我们可以在headers添加Cookie,达到发送Cookie的目的 - 基本实例
import requests
url = 'https://zhuanlan.zhihu.com/VdnCloud'
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0',
'Cookie': '_zap=1ae92c12-05f5-440d-bfe9-7b702fe986f6; d_c0="AKBluabMjRCPTuZ5kIAigcw5aRkekirKSN8=|1577173904"; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1579164260,1579166647,1579228215,1579228263; _xsrf=S5hUTZJu5nZHCJ6cN1idfGDwJdWMuUex; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1579228266; capsion_ticket="2|1:0|10:1579228233|14:capsion_ticket|44:NjM5NTcxMjRmOTZlNDU4NWFkNzAwODYyYmY1Mjg4Yzc=|d2c986cdcee480ce707d5222f970f795cdcf4f6e33faddab2caff9c00c26dc5a"; KLBRSID=ed2ad9934af8a1f80db52dcb08d13344|1579228266|1579228259'}
response = requests.get(url, headers=header)
print(response.text)
输出(部分)
<!doctype html>
<html lang="zh" data-theme="light"><head><meta charSet="utf-8"/><title data-react-helmet="true">CDN科技专栏|视界云 - 知乎</title><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="google-site-verification" content="FTeR0c8arOPKh8c5DYh_9uu98_zJbaWw53J-Sch9MTg"/><meta data-react-helmet="true" name="description" content="边缘计算服务商|赋能CDN"/><meta data-react-helmet="true" property="og:title" content="CDN科技专栏|视界云"/><meta data-react-helmet="true" property="og:url" content="https:/VdnCloud"/><meta data-react-helmet="true" property="og:description" content="边缘计算服务
商|赋能CDN"/><meta data-react-helmet="true" property="og:image" content="https://pic3.zhimg.com/v2-29117c73dd058337581ac1cfd7205478_b.jpg"/><meta data-react-helmet="true" property="og:site_name" content="知乎专栏"/><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-152.67c7b278.png"/><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-152.67c7b278.png" sizes="152x152"/><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-120.b3e6278d.png" sizes="120x120"/><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-76.7a750095.png" sizes="76x76"/><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-60.a4a761d4.png" sizes="60x60"/><link rel="shortcut icon" type="image/x-icon" href="https://static.zhihu.com/static/favicon.ico"/><link rel="search" type="application/opensearchdescription+xml" href="https://static.zhihu.com/static/search.xml" title="知乎"/><link rel="dns-prefetch" href="//static.zhimg.com"/><link rel="dns-prefetch" href="//pic1.zhimg.com"/><link rel="dns-prefetch" href="//pic2.zhimg.com"/><link rel="dns-prefetch" href="//pic3.zhimg.com"/><link rel="dns-prefetch" href="//pic4.zhimg.com"/><style>
7. 会话维持
python每次对一个url的请求都相当与打开一个新的浏览器对网站进行请求,这样使我们的会话无法维持,虽然可以通过Cookie来登录,但是这样显得有些麻烦,并且我们不清楚网站的Cookie机制,可能是转瞬即逝的Cookie。在requests中我们可以通过Session放法来维持会话,简单暴力高效,直接看一下实例吧
- 基本实例(不使用session)
import requests
requests.get('http://httpbin.org/cookies/set/username/admin') # 添加一个Cookie信息,username=admin
url = 'http://httpbin.org/cookies'
response = requests.get(url) # 获取cookie信息
print(response.text)
输出
{
"cookies": {}
}
我们可以看到,会话已经不是之前设置Cookie的那个会话了
- 基本实例(使用session)
import requests
s = requests.Session() # 使用sesson维持会话
s.get('http://httpbin.org/cookies/set/username/admin') # 添加一个cookie信息
url = 'http://httpbin.org/cookies'
response = s.get(url) # 获取信息
print(response.text)
输出
{
"cookies": {
"username": "admin"
}
}
获取到了信息,会话维持成功
Session在平常的使用中非常广泛,可以模拟浏览器打开同一个站点的不用页面。
8. 代理设置
当对网站频繁访问时,我们容易被ban,ip遭到封禁,导致我们在一段时间内无法访问。为了防止我们自己的ip被ban,我们可以使用代理ip,就算封也是封的代理ip,我们只需要换一个代理ip就可以了。在requests中我们可以使用proxies参数来设置。
- 基本示例
import requests
proxy = {'http': 'daili_ip_1', # 在实际应用中请换成自己的代理ip
'https': 'daili_ip_2'}
response = requests.get('your-ip', proxies=proxy)
print(response.text)
9. 超时设置
为防止服务器不能及时响应,大部分发至外部服务器的请求都应该带着 timeout 参数。在默认情况下,除非显式指定了 timeout 值,requests 是不会自动进行超时处理的。如果没有 timeout,你的代码可能会挂起若干分钟甚至更长时间。
- 基本示例
import requests
url = 'https://www.jd.com/'
response = requests.get(url, timeout=1) # 设置超时时间为1秒
print(response.text)
实际上请求分为两个过程,连接和读取,上面这样设置timeout指的是连接和读取过程的总时间。如果我们要分别设置,我们可以传入一个元组。
- 基本示例
import requests
url = 'https://www.jd.com/'
response = requests.get(url, timeout=(5, 30)) # 设置超时时间连接为5秒,读取为30秒
print(response.text)