requests模块
requests模块
能够模拟浏览器发送请求 比urllib模块更加的方便
该模块不是自带的模块需要提前下载
pip3 install requests
# 如果你下载的模块想指定版本 需要在模块名的后面加两个等号
# pip3 install django==1.11.11
基本使用
import requests # 导入模块
requests.get() # 朝服务端发送get请求
requests.post() # 朝服务端发送post请求
res = requests.get("https://www.baidu.com")
res.status_code # 获取响应状态码
res.encoding = 'utf-8' # 修改编码
print(res.text) # 获取页面HTML代码
with open(r'爬取页面.html','w',encoding='utf-8') as f:
f.write(res.text) # 写入文件
加请求头
headers
加携带的参数
params
如果涉及到转码需要用模块
from urllib.parse import urlencode
res1 = urlencode(params,encoding='utf-8')
print(res1)
wd=%E7%BE%8E%E5%A5%B3
网站的防爬措施
1.校验请求头中否是否包含User-Agent参数(当前是否是浏览器身份)
随便找一个网站打开network发送请求查找拷贝即可
user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
2.校验请求头中的referer参数
用于表明当前请求是从哪里过来的
有一些网站会直接限制死 只有是从本网站来的请求才会被允许访问
其他网站过来的一律不让访问
针对上述两种防爬措施如何破解
res = requests.get('https://www.baidu.com')
# get还支持携带额外的参数
1.请求头参数
requests.get(url,headers={
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36',
'referer': 'https://xiaoyuan.lagou.com/'
})
# 如果headers里面参数较多 并且在多个requests方法里面都需要使用的话 你可以将请求头参数单独写成一个字典
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36',
'referer': 'https://xiaoyuan.lagou.com/'
}
requests.get(url1,headers=headers)
requests.get(url2,headers=headers)
requests.get(url3,headers=headers)
2.get请求如何携带额外的参数
url?username=jason&password=123
# 1 可以直接在url后面写
requests.get(url?username=jason&password=123)
# 2 单独将参数提取出来
requests.get(url1,
headers=headers,
params = {
'username':'******',
'password':'******'
}
)
"""
注意针对携带的参数如果里面有中文 可能需要你自己转码
from urllib.parse import urlencoded
res = urlencoded({'wd':'美女'})
"""
3.如何携带cookie参数
1.要么在请求头里面书写
requests.get(url,headers={
'cookie':{
'asd':'sadsad',
'sad':'sadsad'
}
})
2.要么单独书写(推荐)
cookies = {
'asd':'sadsad',
'sad':'sadsad'
}
requests.get(url,headers=headers,params=params,cookies=cookies)
cookie与session
HTTP协议四大特性
1.基于TCP/IP作用于应用层之上的协议
2.基于请求响应
3.无状态
4.无连接
无状态
不保存用户状态,所有的用户无论来多少次对于服务端来说都是初见
针对无状态的特点我们需要找到一种可以记录客户端状态的方法
cookie
保存在客户端浏览器上面的键值对
就拿登录功能举例
当你第一次输入了用户名和密码之后
我的服务端会给你返回一个随机字符串 你保存在浏览器上
之后再访问服务端的时候你把这个随机字符串带给我
我来校验这个字符串跟我之前给你这个用户的是否
username 123456
password ******
session
保存在客户端浏览器上面的明文键值对极有可能会被偷看到或者抓取到从而直接看到用户的用户名和密码
当用户第一次输入用户名和密码成功之后,服务端不再直接让浏览器保存用户的用户名和密码,而是给浏览器发送一个随机的字符串保存下来,然后在服务端这边保存随机字符串与用户名密码的对应关系
以后浏览器只需要发送随机字符串到服务端,服务端完成身份的比对
保存在服务端上面的与用户相关的key:value键值对数据
"""
1.无论是cookie还是session都存在安全隐患
只不过session安全系数比cookie要高
2.目前所有的用来保存用户信息的技术都必须依赖于cookie
3.浏览器有资格拒绝保存cookie
4.浏览器也可以禁用网站的js代码
"""
超时设置
#超时设置
#两种超时: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)
异常处理
# 万能异常
try:
# kasd
l = [111,222]
l[3]
except Exception as e:
print(e)
发送文件
import requests
files={'file':open('a.txt','rb')}
respone=requests.post('http://httpbin.org/post',
files=files)
print(respone.status_code)
解析json
#解析json
import requests
response=requests.get('http://httpbin.org/get')
import json
res1=json.loads(response.text) #太麻烦
res2=response.json() #直接获取json数据
print(res1 == res2) #True
主要使用方法
# 必备知识点
import requests
requests.post(
url,
headers,
data, # 发送post请求携带的数据(请求体里面的数据)
params, # get请求可以携带的数据
)
res = requests.post(
url='http://www.aa7a.cn/user.php',
data=data,
headers=headers
)
cookie = res.cookies.get_dict() # 直接获取cookie的字典格式数据
import re
# 从上述字符串中获取a标签里面的href
res_exp = '<a href="(.*?)" class="*****">'
res1 = re.findall(res_exp,res.text)
# 写入文件
with open(file_path,'wb') as f:
# 一行行读取视频数据写入文件
for line in res3.iter_content(): # 获取二进制流数据
f.write(line)
# 拼接路径 千万不要手动拼接 因为不同的操作系统路径分隔符不一样
import os
file_path = os.path.join(root_path,file_name)
利用requests模块模拟网站的登录
1.先用浏览器正常的访问登录页面
2.打开network查看登录的地址是什么
3.再看请求体里面数据的构造
4.最好也将请求头里面两个常见的头加上user-agent,referer
5.请求体里面的数据
有些网站针对密码是加密之后再发送
你就需要先用浏览器输入正确的验证码获取加密之后的结果放入requests请求中
如果直接是明文那么直接写即可
6.发送正确的用户名和密码之后完成登录 返回的页面上应该是带有你的用户名的
requests.get(params={},cookies={})
requests.post(data={},cookies={})
如果登录成功,cookie会存在于res对象中
cookie=res.cookies.get_dict() # 为了让发送更加简单
1.有些网站在初次访问的时候就会给你一些cookie但是这些cookie都是没有激活的,没有任何的作用,但是当你登录成功之后网站会将之前发你的cookie在后台偷偷的激活一下
2.一开始会返回给你一个cookie,但你登录之后又会给你返回一个cookie(这个cookie是用来迷惑你的),第一个cookie才是真正的
爬取梨视频
1.先用浏览器查看一下 然后将页面上的一些链接点一点研究一下它的url变化
2.查看当前页面更多数据加载的特点 找出请求更多数据的url
3.拿着该url尝试着直接在浏览器地址栏里面访问
4.研究该页面的数据的url
5.再去研究该url中视频的url地址
6.浏览器拿到的页面一开始的时候不一定就是完完全全的页面
******************************************
页面上重要的数据可能是通过后续的js代码动态加载的
如果是动态加载的 你需要找到该js代码 去找地址
******************************************
总结
如何获取网页的二进制数据
res = requests.get(url='https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=1&start=0')
print(res.content)
如何获取二进制流数据(一行行读取)
res3 = requests.get(url='https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=1&start=0')
for line in res3.iter_content(): # 获取二进制流数据
f.write(line)
补充
***************************************
有时候浏览器获取到的html文件并不是一个完整的文件
上面的HTML标签有一些是直接写死的 直接就可以查看到
而有一些是通过后续的js代码动态加载出来的 你是查看不到的
***************************************
requests-html模块
使用此库时,您将自动获得:
全面的JavaScript支持!
CSS选择器(又名jQuery风格,多亏了PyQuery)。
XPath Selectors,使您感到内fa。
模拟的用户代理(如真实的Web浏览器)。
自动跟随重定向。
连接池和cookie持久性。
您知道和喜欢的请求体验具有神奇的解析能力。
http://requests-html.kennethreitz.org/
https://github.com/psf/requests-html
# 支持异步
from requests_html import AsyncHTMLSession
asession = AsyncHTMLSession()
async def get_pythonorg():
r = await asession.get('https://www.baidu.com/')
return r
async def get_reddit():
r = await asession.get('https://www.jd.com/')
return r
async def get_google():
r = await asession.get('https://www.sogo.com/')
return r
results = asession.run(get_pythonorg, get_reddit, get_google)
# results # check the requests all returned a 200 (success) code
# [<Response [200]>, <Response [200]>, <Response [200]>]
# Each item in the results list is a response object and can be interacted with as such
for result in results:
print(result.html.url)
# 支持js调用
r = session.get('http://python-requests.org/')
r.html.render()
r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>'
同步异步
同步
提交完请求之后原地等待任务的返回结果,什么时候有结果什么时候继续下一步操作
异步
提交完请求之后不愿地等待任务的返回结果直接执行下一个动作,任务后期会通过异步回调机制获取
"""
异步效率肯定比同步高
"""