问题情景

混淆群内的小伙伴遇到这么个问题,Mailivery 这个网站登录后,明明提交的表单(邮箱和密码也正确)、请求头等等都没问题,为啥一直重定向到登录页面呢?唉,该出手时就出手啊,我也看看咋回事吧!

登录参数分析

显而易见,需要:邮箱(有邮箱校验)、密码

打开开发者工具,随意输入邮箱和密码登录,查看登录接口的请求和方法:

请求网址:https://app.mailivery.io/login
请求方法:POST
状态代码:302 Found

302?!重定向吗?在登录不成功后重定向到了登录网站,要求重新登录。目测前后端不分离项目(阿巴阿巴),如果登录成功,肯定会携带登录成功时设置的 Cookie 重定向到主页或者相关主面板。

查看一下登录接口提交头:

POST /login HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 341
Content-Type: application/x-www-form-urlencoded
Cookie: XSRF-TOKEN=省略; mailivery_session=省略; ......
DNT: 1
Host: app.mailivery.io
Origin: https://app.mailivery.io
Pragma: no-cache
Referer: https://app.mailivery.io/login
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

没有啥加密参数,emm……,很简单,的确是看着很简单,注意 Content-Typeapplication/x-www-form-urlencoded

再看看提交的参数:

_token=lCsu2Ruuw33uHlHkRlKwZG3C2tw7TQBjUoTo1yjz&paid_user_Khe2xqZLA4Tkq3py=&submitted_in_seconds=eyJpdiI6IjJ4OXdFK3ZPZklKUnNadXVtRTk0L3c9PSIsInZhbHVlIjoiNHg5NzJmUjM3UnlDOU1tanlnUHpWdz09IiwibWFjIjoiMDYxYmRkODU0YmY1ZjY0MDk4OWMzNmM5YWU5MjNmZDM4NTg5NzQ1MmM3MzBjNzQ3YjYxNTg0MjliYjFjYzM3OCIsInRhZyI6IiJ9&email=xxx%40foxmail.com&password=123

格式化看一下:

_token: lCsu2Ruuw33uHlHkRlKwZG3C2tw7TQBjUoTo1yjz
paid_user_Khe2xqZLA4Tkq3py:
submitted_in_seconds: eyJpdiI6IjJ4OXdFK3ZPZklKUnNadXVtRTk0L3c9PSIsInZhbHVlIjoiNHg5NzJmUjM3UnlDOU1tanlnUHpWdz09IiwibWFjIjoiMDYxYmRkODU0YmY1ZjY0MDk4OWMzNmM5YWU5MjNmZDM4NTg5NzQ1MmM3MzBjNzQ3YjYxNTg0MjliYjFjYzM3OCIsInRhZyI6IiJ9
email: xxx%40foxmail.com
password: 123

表单提交嘛,多多少少也是带点验证参数,比如这里的:_tokenpaid_user_Khe2xqZLA4Tkq3pysubmitted_in_seconds

经过多次登录提交,发现 _tokensubmitted_in_seconds 的值是变动的,而 paid_user_Khe2xqZLA4Tkq3py 变动的是 paid_user_ 之后的部分。并且这些参数与窗口的 Cookie 相关,如果不一致,将发生 416 错误,提示页面过期。看来这就是个反爬点了,还记得我说的吗,这个网站是前后端不分离,那么这些参数肯定也隐藏于表单,在元素中搜索特色浓重的 submitted_in_seconds

非常的好,可以看到我们这三个参数的来源了,捋一捋:

访问 login 网站(GET) 得到三个参数,此时响应头所设置的 Cookie 无登录效力
对 login 网站(POST) 携带三个参数,根据结果重定向:
如果登录失败,此时响应头所设置的 Cookie 也是无登录效力的,携带 Cookie 要求咱们继续登录
如果登录成功,此时响应头所设置的 Cookie 就是具备登录效力的,携带 Cookie 直接上主页

接下来在 Python 中实现一下,创建 login.pydashboard.py

login.py 实现登录的接口:

import requests

url = "https://app.mailivery.io/login"

_token = ''
paid_user = ''
submitted_in_seconds = ''
email = 'xxx%40163.com'
password = 'xxxxxxx' payload=f'_token={_token}&{paid_user}=&submitted_in_seconds={submitted_in_seconds}&email={email}&password={password}' headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Host': 'app.mailivery.io',
'Origin': 'https://app.mailivery.io',
'Referer': 'https://app.mailivery.io/login',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'Cookie': 'XSRF-TOKEN=eyJpdiI6Ikk1WjFjMFRsdVhKdzBuMjBWamNVVEE9PSIsInZhbHVlIjoiblAzS0ZBOEUyK1lXWGV0ZXhuT1Y5MldLc290d2ZzL0E3dTQxT3BDMmNGR3d6aG0vamhUekozeVFCUVVVczRJSWxxQTM1ZGpvOU5KTm11bFp4NEsvWGlObUJ6V1A3WWc1WFJXcUlPYWYzYTgrSGNMZ2VtM0s1R0tGUlJ4Z0ZMSy8iLCJtYWMiOiI2NGUxYmNhMjEwMmE3ZDNmOTc4OTcxMWVlZGY3ODIyNDZhODBiYzUxZjVhMWE2YWZkMWVhOGM2YjA4MmQzYmY0IiwidGFnIjoiIn0%3D; mailivery_session=eyJpdiI6IjVwL1QwUHNhMTlTdGUyZ0ozUzY3aGc9PSIsInZhbHVlIjoiYlNuSXI2d2tKWjMrYjFpVmx1Ym5uTEVOUGhXZjFKRGhVV1VMeXRHQ1BpRWFsV0ZnYVFkNDd4Vm9wdXY1ZElqVWpVL2xhSytNdnBDYS9NNHRBWmNzRDF4ZjJtWFhPTHFJRFBLVnNYSmFPMW9HSkEweVVpQTZZVjhJU2k5WSswR0oiLCJtYWMiOiJkYzg0ZmY2ODEwZmEyMzczNzU5NGU4YzMwYjA2MDRlZTc0ZWJiNDc4ZDBhMDU4OTgyM2E3NDMzZDM3NmRmNTcxIiwidGFnIjoiIn0%3D',
'Content-Type': 'application/x-www-form-urlencoded',
'Connection': 'keep-alive'
} response = requests.request("POST", url, headers=headers, data=payload, allow_redirects=False, proxies={
'http': None,
'https': None
}) print(response.headers)
print(response.status_code)

注意,我说过,Cookie 和三个参数是有紧密联系的,上述 Cookie 是通过对登录页面 GET 时得到的,三个参数同理。

三个参数的值我已省略,特别特别要注意的是:请求时,allow_redirects这个值最好设置为 False,因为重定向底层和浏览器不同,如果为 True,你会发现你的 Cookie 一直都是失效的。因为产生了如下的重定向过程:

邮箱密码正确的情况:
login -> dashboard -> login
邮箱密码错误的情况:
login -> login
参数未校验的情况:
login -> 页面过期

为什么最终又到 login 了???

我猜测可能是反爬点,动态加载未加载好,太快了,Cookie 或者三个参数在后端都还是未准备好的状况。

我们只需要取得跳转到 dashboard 前响应头中的 Set-Cookie 的值,也就是 XSRF-TOKENmailivery_session

因此我们停止使用 requests 的重定向。

接下来看一下 dashboard.py 这个文件,主要测试一下取得 Cookie 是否有效:

import requests

url = "https://app.mailivery.io/campaign/dashboard"

payload={}
xsrf_token = 'xxx'
mailivery_session = 'xxx' headers = {
'Cookie': f'XSRF-TOKEN={xsrf_token}; mailivery_session={mailivery_session}',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
'Accept': '*/*',
'Host': 'app.mailivery.io',
'Connection': 'keep-alive'
} response = requests.request("GET", url, headers=headers, data=payload, proxies={
'http': None,
'https': None
}) print(response.text)

全套模拟

我们最终的效果是:自动获取三个参数和初始的 Cookie,然后根据邮箱和密码登录,再携带 Cookie 访问 Dashboard。

  1. 自动获取这个很简单,通过 lxml 中的 etree 解析,Cookie 通过 requests 响应头得到。

  2. 然后去登录,也很简单,携带好参数和上一级得到的 Cookie,如果登录密码这些没错,将得到有效的 Cookie。

  3. 最后携带上一级得到的有效 Cookie 进行登录。

如果说你觉得到此结束了,那很抱歉,你再进行上述的实现后,将发现 Cookie 无效!!!

略带一笔,自动获取的表单参数和初始 Cookie 如果有问题,请求时将响应 416。如果没问题,你在取到后立马进行登录,请求将响应 200。200 就一定是好事吗?我已经说过了,要重定向到 dashboard 页面,那么应该是 302 才对!所以我们在取参数到登录这个请求中进行延时,等待后端缓过神,比如 3 秒?4秒?都是可以的。或者你根据响应状态码增加重试机制,尝试到出现 302 的情况。

完整代码就不提供啦,自行琢磨吧~

实战:Mailivery 模拟登录的更多相关文章

  1. Python 爬虫实战5 模拟登录淘宝并获取所有订单

    经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分享,希望大家支持. 本篇内容 python模拟登录淘宝网页 获取登录用户的所有订单详情 ...

  2. Python网络爬虫实战(四)模拟登录

    对于一个网站的首页来说,它可能需要你进行登录,比如知乎,同一个URL下,你登录与未登录当然在右上角个人信息那里是不一样的. (登录过) (未登录) 那么你在用爬虫爬取的时候获得的页面究竟是哪个呢? 肯 ...

  3. Python爬虫入门(基础实战)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  4. python爬虫【实战篇】模拟登录人人网

    requests 提供了一个叫做session类,来实现客户端和服务端的会话保持 使用方法 1.实例化一个session对象 2.让session发送get或者post请求 session = req ...

  5. Python爬虫实战五之模拟登录淘宝并获取所有订单

    经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分享,希望大家支持. 温馨提示 更新时间,2016-02-01,现在淘宝换成了滑块验证了 ...

  6. Python模拟登录实战(三)

    目标:模拟登录知乎 代码如下: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'ziv·chan' import re impor ...

  7. Python模拟登录实战(二)

    目标:1.模拟登录豆瓣,2.自动更改签名和发表说说. 代码如下: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'ziv·chan ...

  8. Python模拟登录实战(一)

    今天,学习了模拟登录新浪微博.模拟登录主要有两种方式,一.利用Cookie:二.模仿浏览器的请求,发送表单. 法一: Cookie:指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密 ...

  9. python爬虫实战(四)--------豆瓣网的模拟登录(模拟登录和验证码的处理----scrapy)

    在利用scrapy框架爬各种网站时,一定会碰到某些网站是需要登录才能获取信息. 这两天也在学习怎么去模拟登录,通过自己码的代码和借鉴别人的项目,调试成功豆瓣的模拟登录,顺便处理了怎么自动化的处理验证码 ...

  10. PHP模拟登录并获取数据

    cURL 是一个功能强大的PHP库,使用PHP的cURL库可以简单和有效地抓取网页并采集内容,设置cookie完成模拟登录网页,curl提供了丰富的函数,开发者可以从PHP手册中获取更多关于cURL信 ...

随机推荐

  1. Python中的分布式框架Ray的安装与使用

    技术背景 假设我们在一个局域网内有多台工作站(不是服务器),那么有没有一个简单的方案可以实现一个小集群,提交分布式的任务呢?Ray为我们提供了一个很好的解决方案,允许你通过conda和Python灵活 ...

  2. 游戏AI LOD交易员(附项目)

    游戏AI的LOD控制 这次我们来一同看看AI LOD的一个另类控制技术,如果你对AI LOD一无所知也没关系,本文会为你们做个科普.但请注意,本文着重讨论其思想, 没有讲代码细节(因为很多涉及数学,有 ...

  3. 画流程图、状态图、时序图、甘特图的JS库-mermaid-js

    参考地址:https://github.com/mermaid-js/mermaid 原生使用方式: <!DOCTYPE html> <html> <head> & ...

  4. servlet一些笔记、详解

    一.什么是servlet? 处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西.理解这个的前提是了解一些http协议的东西,并且知道 ...

  5. 【赵渝强老师】在Spark SQL中读取JSON文件

    Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用.为什么要学习Spark SQL?如果大家了解Hive的话,应该 ...

  6. USB2.0 DP DM VBUS

    在USB 2.0中,设备成功枚举的标志可以通过观察 D+ (dp).D- (dm) 和 VBUS 引脚的电压波形来判断.以下是这些信号在USB 2.0枚举过程中常见的状态: VBUS (5V供电): ...

  7. 墨天轮访谈 | SelectDB 衣国垒:Apache Doris(incubating)1.0版本特性解析与未来规划

    分享嘉宾:衣国垒 Apache Doris Committer.SelectDB 联合创始人&CTO 整理:墨天轮社区 导读 大家好,我是来自Apache Doris社区的衣国垒,也是Sele ...

  8. C# 如何理解装箱和拆箱 ?

    装箱和拆箱就是C# 中数据类型的转换 : 装箱:值类型转换对象类型(引用类型,复杂类型) 拆箱:对象类型转换值类型 object obj=null; //引用类型 obj=1; //装箱 boxing ...

  9. 全局和局部混入 mixins

    使用 mixins 混入 的目的 :复用代码,维护代码 : 局部混入: 全局混入 + 按钮权限控制 : ps:定义一个方法 ,checkPermission (str) str 是按钮的权限标识 , ...

  10. Kubernetes 升级不弃 Docker:KubeKey 的丝滑之道

    作者:尹珉,KubeSphere Ambaasador&Contributor,KubeSphere 社区用户委员会杭州站站长. 引言 随着 Kubernetes 社区的不断发展,即将迎来 K ...