持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
介绍
requests是Python内置的模块,可以帮助我们发送请求,从而实现使用代码控制请求发送。
基于get请求
- 基本请求
import requests
response = requests.get('http://www.zzzfun.com/')
print(response.text)
- 带参数的get请求
有些网站在请求头中需要携带user_agent,如果不携带的话就不会返回正常内容,比如:百度
import requests
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36}'}
response = requests.get('https://www.baidu.com/s?wd=python',
headers = header)
print(response.text)
- 请求地址中携带params(两种方式,推荐第二种)
方式一:
res = requests.get('https://www.baidu.com/s?wd=美女',headers=header)
方式二:
response = requests.get('https://www.baidu.com/s',
headers = header,params={'wd':'漫画'})
print(response.url) # https://www.baidu.com/s?wd=%E6%BC%AB%E7%94%BB
可以通过from urllib.parse import urlencode,unquote进行关键字的编码和解码
print(unquote('%E6%BC%AB%E7%94%BB')) # 漫画
- 带参数的get请求:cookies,两种方式
方式一:在header中放key=value的形式
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
'cookie':'key=v1;key1=v2'
}
response = requests.get('http://127.0.0.1:8000/index/',headers=header)
print(response.text)
方式二:在header中放字典或者CookieJar对象
response=requests.get('http://127.0.0.1:8000/index/',headers=header,cookies={'name':'zhy','age':'18'})
# cookies中的key的值必须是字符串或者是bytes类型
print(response.text)
基于post请求
request.post()用法与request.get()用法完全一致,特殊的是requests.post()有一个data参数,用来存放请求体数据。
- 默认请求头中的编码格式是application/x-www-form-urlencoed,需要使用data传值,否则服务端无法取到值
# 请求头默认编码格式,服务端无法在request.POST中取到数据
response = requests.post('http://127.0.0.1:8000/index/',json={'x':'y'})
# 请求头默认编码格式,服务端可以在request.POST中取到数据
response = requests.post('http://127.0.0.1:8000/index/',data={'x':'y'})
- 请求头可以自定义编码格式application/json,服务端可以在request.post中获取到数据
# 在服务端中获取的数据是b'{"age": 1}'
response = requests.post('http://127.0.0.1:8000/index/',json={'x':'y'})
# 在服务端获取到的数据是b'age=1'
response = requests.post('http://127.0.0.1:8000/index/',data={'x':'y'})
自动携带cookie
session=requests.session()
res=session.post('http://127.0.0.1:8000/index/') # 假设这个请求登录了
res1=session.get('http://127.0.0.1:8000/order/') # 现在不需要手动带cookie,session会帮咱处理
response对象
response=requests.post('http://127.0.0.1:8000/index/',data={'name':'lqz'})
print(response.text) # 响应的文本
print(response.content) # 响应体的二进制
print(response.status_code) # 响应状态码
print(response.headers) # 响应头
print(response.cookies) # cookie
print(response.cookies.get_dict()) # 把cookie转成字典
print(response.cookies.items()) # key和value
print(response.url) # 请求的url
print(response.history) #[]放重定向之前的地址
print(response.encoding) # 响应的编码方式
# 写入文件
response.iter_content() # 获取二进制流:图片,视频,大文件,一点一点循环取出来
with open('a','wb') as f:
for line in response.iter_content():
f.write(line)
编码问题
import requests
response=requests.get('http://www.autohome.com/news')
# response.encoding='gbk' #汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
print(response.text)
解析json
import json
respone=requests.post('http://127.0.0.1:8000/index/',data={'name':'lqz'})
print(type(respone.text)) # 响应的文本
print(json.loads(respone.text))
print(respone.json()) # 相当于上面那句话
print(type(respone.json())) # 相当于上面那句话
高级用法---ssl
#证书验证(大部分网站都是https)
import requests
respone=requests.get('https://www.12306.cn') #如果是ssl请求,首先检查证书是否合法,不合法则报错,程序终端
#改进1:去掉报错,但是会报警告
import requests
respone=requests.get('https://www.12306.cn',verify=False) #不验证证书,报警告,返回200
print(respone.status_code)
#改进2:去掉报错,并且去掉警报信息
import requests
from requests.packages import urllib3
urllib3.disable_warnings() #关闭警告
respone=requests.get('https://www.12306.cn',verify=False)
print(respone.status_code)
#改进3:加上证书
#很多网站都是https,但是不用证书也可以访问,大多数情况都是可以携带也可以不携带证书
#知乎\百度等都是可带可不带
#有硬性要求的,则必须带,比如对于定向的用户,拿到证书后才有权限访问某个特定网站
import requests
respone=requests.get('https://www.12306.cn',
cert=('/path/server.crt',
'/path/key'))
print(respone.status_code)
高级用法---使用代理
respone=requests.get('http://127.0.0.1:8000/index/',proxies={'http':'代理的地址和端口号',})
代理:免费代理,收费代理花钱买
代理池:列表放了一堆代理ip,每次随机取一个,再发请求就不会封ip了
高匿和透明代理?如果使用高匿代理,后端无论如何拿不到你的ip,使用透明,后端能够拿到你的ip。
后端如何拿到透明代理的ip, 后端:X-Forwarded-For
超时设置
#超时设置
#两种超时:float or tuple
#timeout=0.1 #代表接收数据的超时时间
#timeout=(0.1,0.2)#0.1代表链接超时 0.2代表接收数据的超时时间
import requests
respone=requests.get('https://www.baidu.com',
timeout=0.0001)
认证设置(比较古老)
import requests
r=requests.get('xxx',auth=('user','password'))
print(r.status_code)
异常处理
import requests
from requests.exceptions import * #可以查看requests.exceptions获取异常类型
try:
r=requests.get('http://www.baidu.com',timeout=0.00001)
except ReadTimeout:
print('===:')
except Exception as e:
print(e)
上传文件
res=requests.post('http://127.0.0.1:8000/index/',files={'files':open('fox.jpg','rb')})
print(res.text)
模拟登陆网站:www.aa7a.cn/
import requests
session = requests.session()
data = {
'username': '1280135234@qq.com',
'password': 'zhuang1026',
'captcha': 2222,
'remember': 1,
'ref': 'http://www.aa7a.cn/user.php?act=logout',
'act': 'act_login',
}
res = session.post('http://www.aa7a.cn/user.php',data=data)
print(res.text)
cookie = res.cookies
print(cookie)
result = session.get('http://www.aa7a.cn/index.php')
print('1280135234@qq.com' in result.text)
爬取梨视频
import requests
import re
# 点击加载更多会发送ajax请求,打开network得到请求的地址
res = requests.get('https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=9&start=0')
# print(res.text)
# 每次加载12个视频,每个视频对应一个li标签,通过正则匹配得到a标签内的网址
re_video = '<a href="(.*?)" class="vervideo-lilink actplay">'
video_urls = re.findall(re_video,res.text)
for video in video_urls:
url = 'https://www.pearvideo.com/'+video
res_video = requests.get(url)
# print(res_video.text)
# break
re_video_mp4 = 'hdflvUrl="",sdflvUrl="",hdUrl="",sdUrl="",ldUrl="",srcUrl="(.*?)",vdoUrl=srcUrl,skinRes="//www.pearvideo.com/domain/skin",videoCDN="//video.pearvideo.com";'
video_url = re.findall(re_video_mp4,res_video.text)[0]
# print(video_url)
res_video_content = requests.get(video_url)
video_name = video_url.rsplit('/',1)[-1]
with open(video_name,'wb') as f:
for line in res_video_content.iter_content():
f.write(line)