python模拟登陆
1.模拟登陆分类
1.1暴力模拟登陆
暴力模拟登陆:忽略web设计原理,忽略登陆需求,硬性的将cookie取出加载爬虫当中进行登录。
1.2 原理分析模拟登陆
原理分析模拟登陆: 根据网站源码和抓包请求,分析网站登录原理,用代码依照登录原理向服务器具体接口提交具体数据,实现模拟登录,技术含量最高,难度最大。
1.3浏览器驱动模拟登陆
浏览器驱动模拟登陆:使用Python调用浏览器驱动,执行浏览器行为(发送数据,点击),进行模拟登陆,这种模拟登陆由于难度低,逐渐被一些项目认可,但是效率低。
(1)正常浏览器模拟登陆
(2)无头浏览器模拟登陆
2.cookie原理
2.1 cookie定义
(1)Cookie(曲奇,小饼干):是服务器下发给浏览器用于识别用户身份的校验值。
(2)Cookie是实现当前web身份识别的基础手段,具有一定的不安全性,因为:
①cookie下发,浏览器可以拒收
②cookie下发到浏览器本地,容易被重写伪装
2.2查看cookie下发和提交
以京东登录为例我们来查看cookie的下发和提交
2.2.1 cookie下发
Cookie的下发是在和http请求的response headers当中,且响应里提到了字符集是GBK
2.2.2 cookie提交
Cookie的提交是携带在http request headers当中
2.2.3 cookie总结
有上面得到我们在写爬虫的时候
(1)需要关心cookie的下发,我们需要保存下发的cookie来维持自己的身份
(2)需要关心提交的cookie
(3)所有的Python爬虫模块默认都不携带cookie
3.常用的cookie保存方法
3.1 urllib系列
Urllib系列保存cookie需要借助一个内置模块
Python2 : cookielib
Python3 : http.cookiejar
3.1.1 不保存cookie
(1)代码
(2)结果
3.1.2 保存cookie
(1)代码
(2)结果
打开保存下来的cookie文件
3.2 requests系列
3.2.1 Requests.session
(1)Requests是手写Python最受欢迎的模块,但是和urllib一样,他默认不保存cookie,
(2)如果涉及到cookie就要用request.session方法来实现。
3.2.2 Post模拟登陆分析
3.2.2.1 页面请求分析
以我爱我家为例,从登录页开始,在打开登录页前打开抓包工具
3.2.2.2 找对应url的包
3.2.2.3 查看下发的cookie
确定请求成功,和发现请求登录页面(不是请求登录),服务器下发了cookie,那么这样很可能在我们请求登录的时候,服务器要检测cookie,所以我们要记录这里的cookie
3.2.2.4 开始页面结构分析
(1)提交的表单是不是在当前页,防止iframe标签
(2)查看是否是常规的form表单提交
①有没有action和method
②Action提交的位置,默认为当前url
③Method 提交的方式 默认为get
④是否有submit按钮
⑤查看表单是否有hidden域
input的类型为hidden的时候,在HTML当中不会显示,但是可以提交
3.2.2.5 分析总结
(1)登录是一个post请求
(2)登录的数据传递给了/passport/sigin?city=bj,所以一会儿要抓这个包
(3)我们请求登录的数据是:input传值是根据name传的
username、password、aim、service、status
3.2.2.6 测试请求数据
返回状态为200,表示请求成功
form-data和刚才我们分析的form请求数据进行比对(用户名密码加3个参数),发现一致,那么可以爬取了。
3.2.3 代码如下
3.2.3.1 获取cookie
(1)代码
(2)结果
3.2.3.2 获取form hidden的值
(1)代码
# coding:utf-8
import requests
from lxml import etree
# 请求登录页面,获取cookie
login_index_url = "https://passport.5i5j.com/passport/login?service=https%3A%2F%2Fwx.5i5j.com%2Freglogin%2Findex%3FpreUrl%3Dhttps%253A%252F%252Fwx.5i5j.com%252F%253Fpmf_group%253Dbaidu%2526pmf_medium%253Dppzq%2526pmf_plan%253D%2525E5%2525B7%2525A6%2525E4%2525BE%2525A7%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_unit%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_keyword%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_account%253D199&status=1&city=wx"
login_index_headers = {
"Referer": "https://wx.5i5j.com/?pmf_group=baidu&pmf_medium=ppzq&pmf_plan=%E5%B7%A6%E4%BE%A7%E6%A0%87%E9%A2%98&pmf_unit=%E6%A0%87%E9%A2%98&pmf_keyword=%E6%A0%87%E9%A2%98&pmf_account=199",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
}
# 为了保存cookie我们用requests.session进行请求
session = requests.session()
login_index_response = session.get(login_index_url,headers=login_index_headers)
result = login_index_response.content.decode()
html = etree.HTML(result)
# 取出aim的值
aim = html.xpath(r"//input[@id='aim1']")[0].attrib
aim = aim["value"]
# 取出service的值
service = html.xpath(r"//input[@id='service']")[0].attrib
service = service["value"]
# 取出status的值
status = html.xpath(r"//input[@id='status1']")[0].attrib
status = status["value"]
# 打印出三个值
print(aim)
print(service)
print(status)
(2)结果
3.2.3.3 完整请求登录代码
(1)代码
# coding:utf-8
import requests
from lxml import etree
# 请求登录页面,获取cookie
login_index_url = "https://passport.5i5j.com/passport/login?service=https%3A%2F%2Fwx.5i5j.com%2Freglogin%2Findex%3FpreUrl%3Dhttps%253A%252F%252Fwx.5i5j.com%252F%253Fpmf_group%253Dbaidu%2526pmf_medium%253Dppzq%2526pmf_plan%253D%2525E5%2525B7%2525A6%2525E4%2525BE%2525A7%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_unit%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_keyword%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_account%253D199&status=1&city=wx"
login_index_headers = {
"Referer": "https://wx.5i5j.com/?pmf_group=baidu&pmf_medium=ppzq&pmf_plan=%E5%B7%A6%E4%BE%A7%E6%A0%87%E9%A2%98&pmf_unit=%E6%A0%87%E9%A2%98&pmf_keyword=%E6%A0%87%E9%A2%98&pmf_account=199",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
}
#为了保存cookie我们用requests.session进行请求
session = requests.session()
login_index_response = session.get(login_index_url,headers=login_index_headers)
result = login_index_response.content.decode()
html = etree.HTML(result)
aim = html.xpath(r"//input[@id='aim1']")[0].attrib
aim = aim["value"]
service = html.xpath(r"//input[@id='service']")[0].attrib
service = service["value"]
status = html.xpath(r"//input[@id='status1']")[0].attrib
status = status["value"]
data = {
"username": "182xxxxxxxx",
"password": "xxxxxx",
"aim": aim,
"service": service,
"status":status
}
# 请求登录的url
login_url = "https://passport.5i5j.com/passport/sigin?city=wx"
login_headers = {
"https":"//passport.5i5j.com/passport/login?service=https%3A%2F%2Fwx.5i5j.com%2Freglogin%2Findex%3FpreUrl%3Dhttps%253A%252F%252Fwx.5i5j.com%252F%253Fpmf_group%253Dbaidu%2526pmf_medium%253Dppzq%2526pmf_plan%253D%2525E5%2525B7%2525A6%2525E4%2525BE%2525A7%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_unit%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_keyword%253D%2525E6%2525A0%252587%2525E9%2525A2%252598%2526pmf_account%253D199&status=1&city=wx",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
}
login_response = session.post(login_url,headers =login_headers,data = data )
login_result = login_response.content.decode()
print(login_result)
(2)结果