我们通过模拟微博登录这个例子来看看如何使用Charles分析网站加载流程,顺便把微博模拟登录的Python代码也给实现了。

Charles是一个网络抓包工具,跟Fiddler一样,你哪个用的顺手就用那个。

抓包是写爬虫的必备技能,熟练的使用抓包工具能使分析效率极大提高,当然这过程中也少了分析逻辑。

1. 用Charles记录整个登录过程

首先,我们运行Charles并开始记录。然后打开Chrome浏览器,选择使用Charles代理,打开微博首页 ,出现登录页面(如果之前登录过微博,要先退出登录)。输入用户名和密码进行登录,登录成功后就可以停止Charles的记录。这样我们就用Charles完整记录下了微博的登录过程。见图:

我们把整个登录过程写出一个Python类,它的定义为:

class WeiboLogin:    user_agent = (        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.11 (KHTML, like Gecko) '        'Chrome/20.0.1132.57 Safari/536.11'    )    def __init__(self, username, password, cookies_tosave='weibo.cookies'):        self.weibo_user = username        self.weibo_password = password        self.cookies_tosave = cookies_tosave        self.session = requests.session()        self.session.headers['User-Agent'] = self.user_agent

接下来我们分析登录过程,并逐一实现这个类的各个方法。

2. 分析登录过程

把Charles的主窗口切换到“Sequence”标签页,

我们可以按加载时间顺序观察Charles记录的微博登录过程,我们发现第一个可疑的请求的Host是:

  • login.sina.com.cn

点击该条记录,下方出现该条请求的完整内容,它的路径是:

GET /sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.19)&_=1542456042531 HTTP/1.1

这个GET请求的参数_=1542456042531看起来是个时间戳,这个在ssologin.js(看后面是如何找到的)定义为preloginTimeStart,可以用int(time.time()*1000)得到。

从prelogin.php这个名字看,它是一个预登陆,即在你输入用户名和密码前,它先从服务器拿点东西过来:

用Python实现这个prelogin:

    def prelogin(self):        preloginTimeStart = int(time.time()*1000)        url = ('https://login.sina.com.cn/sso/prelogin.php?'               'entry=weibo&callback=sinaSSOController.preloginCallBack&'               'su=&rsakt=mod&client=ssologin.js(v1.4.19)&'               '_=%s') % preloginTimeStart        resp = self.session.get(url)        pre_login_str = re.match(r'[^{]+({.+?})', resp.text).group(1)        pre_login = json.loads(pre_login_str)        pre_login['preloginTimeStart'] = preloginTimeStart        print ('pre_login 1:', pre_login)        return pre_login

这些预先拿过来的东西有什么用呢?目前为止还不知道,继续往下看。

补充:关于认证码
昨天最初写这篇教程的时候,没有碰到验证码。今天就碰到验证码跳出来了,真是大快人心,可以把这部分补充上了。

对比昨天的prelogin的URL参数不能发现,今天的多了两个参数:

  • su=xxxxx 就是加密的那个(实为base64编码)用户名

  • checkpin=1 告诉服务器要检查验证码(我去,自己写爬虫绝对不会这么干)

带着这两个参数请求服务器,返回来的也会多了showpin的值:

既然要显示pin(验证码),就要下载验证码,它的地址是:

https://login.sina.com.cn/cgi/pin.php?r=2855501&s=0&p=aliyun-a34a347956ab8e98d6eb1a99dfddd83bc708

这个是怎么来的呢?直接按Ctrl+F 打开“Text to Find”窗口搜索“pin.php”:

这个Find窗口很有用,它让我们可以在记录的所有请求和响应里面查找特定文本,并且它还支持正则表达式、大小写敏感、只找全词。只找全词,对查找su这样的短词很有帮助,可以过滤大量包含它的词,比如super。

这里要特别说明一下,为什么只选在”Response Body”里面查找。
因为我们是要找上面的URL是如何生成的,我们认为它是在某个js文件的某段代码实现的,所以它一定是在 Response Body 里面的,这样也可以过滤掉很多无关信息。

通过上面的过滤,直接就定位了相关代码,双击进去,再稍微一搜,就发现对应的代码了:

var pincodeUrl = "https://login.sina.com.cn/cgi/pin.php";...return pincodeUrl + "?r=" + Math.floor(Math.random() * 100000000) + "&s=" + size + (pcid.length > 0 ? "&p=" + pcid : "")

有了这个js,用Python来实现就易如反掌了,小猿们可以自己试试看。

有了验证码的URL,我们就用self.session下载它并保存为文件,在POST 所有login数据前,通过pin = input('>>please input pin:')来获取,加入到POST数据里面一起POST发送即可。

第二条可疑的请求的Host跟第一条一样,路径是:

POST /sso/login.php?client=ssologin.js(v1.4.19) HTTP/1.1

这是一条POST,我来看看它POST的数据,选择这条记录,点击“Contents”标签,再点击“Form”标签,可以看到它POST的数据:

这时候我们可以把这写POST的参数和prelogin得到的联系起来了。

参数:su
这个看上去是“加密”的username,即用户名。那它是怎么加密的呢?浏览器运行的是JavaScript,所以我们猜测是通过JS加密的,那么是哪段JS呢?看上面login.php路径里给了参数client=ssologin.js(v1.4.19),那我们就去ssologin.js里面找找,选择加载这个js文件的请求,“Contents”标签下面就会显示JS代码,按Ctrl+F查找username:

果然在这里,其实就是用base64编码了一下,算不上加密,于是我们就有了获得su的方法:

    def encrypt_user(self, username):        user = urllib.parse.quote(username)        su = base64.b64encode(user.encode())        return su

**参数:sp**
跟su同样的思路,还是在ssologin.js里面查找password,我们发现了加密password的算法:

于是有了获得sp的方法:

    def encrypt_passwd(self, passwd, pubkey, servertime, nonce):        key = rsa.PublicKey(int(pubkey, 16), int('10001', 16))        message = str(servertime) + '\t' + str(nonce) + '\n' + str(passwd)        passwd = rsa.encrypt(message.encode('utf-8'), key)        return binascii.b2a_hex(passwd)

参数:prelt
既然ssologin.js就是管登录的,那我们还是在这里找prelt,Ctrl+F 查找到

request.prelt = preloginTime;

原来prelt就是preloginTime的简称,那我们再搜索preloginTime:

preloginTime = (new Date()).getTime() - preloginTimeStart - (parseInt(result.exectime, 10) || 0)

这里的preloginTimeStart就是请求prelogin.php时的时间戳,result.exectime就是prelogin请求返回结果里面的exectime。
哈哈哈,又找到了prelt的算法,其实这个prelt就是从请求开始到现在的时间差,似乎也没那么重要,随机一个就可以,不过还是用Python实现一下:

    def get_prelt(self, pre_login):        prelt = int(time.time() * 1000) - pre_login['preloginTimeStart'] - pre_login['exectime']        return prelt

目前,我们已经获得了登录的重要参数,接下来再看看登录请求的流程,在“Sequence”的 “Filter” 输入login,我们可以看到过滤后的请求,其中前三个就是登录的先后顺序:

其详细流程就是:

  1. prelogin从服务器获得一些参数

  2. 把加密的用户名密码等参数POST给https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)

  3. 第2步返回的是html代码,html代码里面重定向到另外的url (所以我们代码里面也要实现这个重定向)

  4. 第3步返回的还是html代码,里面通过JS先实现几个跨域设置,最后重定向到另外一个url(我们也要实现这部分操作)

第4步返回的HTTP头里面重定向到另外的URL,request会跟随这个重定向,不用我们实现。
用Python实现html代码里面的JS重定向的方法就是,用正则表达式提取出JS代码里面的重定向URL,然后用requests做GET请求。

完整的登录流程的代码就是:

    def login(self):        # step-1. prelogin        pre_login = self.prelogin()        su = self.encrypt_user(self.weibo_user)        sp = self.encrypt_passwd(            self.weibo_password,            pre_login['pubkey'],            pre_login['servertime'],            pre_login['nonce']        )        prelt = self.get_prelt(pre_login)        data = {            'entry': 'weibo',            'gateway': 1,            'from': '',            'savestate': 7,            'qrcode_flag': 'false',            'userticket': 1,            'pagerefer': '',            'vsnf': 1,            'su': su,            'service': 'miniblog',            'servertime': pre_login['servertime'],            'nonce': pre_login['nonce'],            'vsnf': 1,            'pwencode': 'rsa2',            'sp': sp,            'rsakv' : pre_login['rsakv'],            'encoding': 'UTF-8',            'prelt': prelt,            'sr': "1280*800",            'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.'                   'sinaSSOController.feedBackUrlCallBack',            'returntype': 'META'        }        # step-2 login POST        login_url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'        resp = self.session.post(login_url, data=data)        print(resp.headers)        print(resp.content)        print('Step-2 response:', resp.text)        # step-3 follow redirect        redirect_url = re.findall(r'location\.replace\("(.*?)"', resp.text)[0]        print('Step-3 to redirect:', redirect_url)        resp = self.session.get(redirect_url)        print('Step-3 response:', resp.text)        # step-4 process step-3's response        arrURL = re.findall(r'"arrURL":(.*?)\}', resp.text)[0]        arrURL = json.loads(arrURL)        print('CrossDomainUrl:', arrURL)        for url in arrURL:            print('set CrossDomainUrl:', url)            resp_cross = self.session.get(url)            print(resp_cross.text)        redirect_url = re.findall(r'location\.replace\(\'(.*?)\'', resp.text)[0]        print('Step-4 redirect_url:', redirect_url)        resp = self.session.get(redirect_url)        print(resp.text)        with open(self.cookies_tosave, 'wb') as f:            pickle.dump(self.session.cookies, f)        return True

代码中打印了很多信息,方便我们过程整个登录过程。

要测试我们的实现就很简单了:

if __name__ == '__main__':    weibo_user = 'your-weibo-username'    weibo_password = 'your-weibo-password'    wb = WeiboLogin(weibo_user, weibo_password)    wb.login()

修改为你的微博账户和密码就可以测试起来啦。

antdesignpro 重定向到登录页面_爬虫技巧:使用Charles和requests模拟微博登录相关推荐

  1. python爬虫登录微博_为爬虫获取登录cookies: 使用Charles和requests模拟微博登录

    上一节,我们讲了如何配置Charles代理,这一节我们通过模拟微博登录这个例子来看看如何使用Charles分析网站加载流程,顺便把微博模拟登录的Python代码也给实现了. 1. 用Charles记录 ...

  2. python爬虫登录微博_python爬虫-模拟微博登录

    微博模拟登录 这是本次爬取的网址:https://weibo.com/ 一.请求分析 找到登录的位置,填写用户名密码进行登录操作 看看这次请求响应的数据是什么 这是响应得到的数据,保存下来 exect ...

  3. python爬虫登录微博_python爬虫-模拟微博登录功能

    微博模拟登录 这是本次爬取的网址:https://weibo.com/ 一.请求分析 找到登录的位置,填写用户名密码进行登录操作 看看这次请求响应的数据是什么 这是响应得到的数据,保存下来 exect ...

  4. spring boot 自动跳转登录页面_徒手撸一个扫码登录示例工程

    徒手撸一个扫码登录示例工程 不知道是不是微信的原因,现在出现扫码登录的场景越来越多了,作为一个有追求.有理想新四好码农,当然得紧跟时代的潮流,得徒手撸一个以儆效尤 本篇示例工程,主要用到以下技术栈 q ...

  5. HTML+CSS+JavaScript制作登录页面_科幻后台登录界面html模板_科技感登录界面html模板

    科幻后台登录界面html模板 原始HTML+CSS+JS页面设计,这是一个不错的登录网页制作,画面精明,非常适合初学者学习使用. 作品介绍 1.网页作品简介方面 :蓝色科技风格后台登录框,科幻的网站后 ...

  6. php怎么实现登录后管理员和普通会员的不同的登录页面_智学网怎么登录 智学网怎么查分数 智学网统一登录平台网址分享https://www.zhixue.com/login.html...

    阅读本文前,请您先点击上面的"蓝色字体",再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 注:本文转载自网络,不代表 ...

  7. react登录页面_「开源」React-Admin终极后台管理项目解决方案

    前端chenghao大神的作品,页面非常完善漂亮,不折不扣的企业级作品.学习react的小伙伴不可错过的好东西. 功能模块 首页 完整布局 换肤(全局功能,暂时只实现了顶部导航的换肤,后续加上其他模块 ...

  8. bootstrap设计登录页面_前端小白如何在10分钟内打造一个爆款Web响应式登录界面?...

    对于前端小白(例如:专注后端代码N年的攻城狮),自己编写一个漂亮的Web登录页面似乎在设计上有些捉襟见肘,不懂UI设计,颜色搭配极度的混乱(主色,辅助色,配色,色彩渐变,动画效果等等,看起来一堆乱七八 ...

  9. python爬取二级页面_爬虫代码改进(二)|多页抓取与二级页面

    本文是下面两篇文章的续篇 本系列包括如下内容抓取豆瓣top250一页多个字段 整合成列表 存储为json文件 定义成函数形式 多页抓取之构造url 多页抓取之翻页 抓取二级页面数据 通过生成器优化代码 ...

  10. HTML+CSS+JavaScript制作登录页面_科幻后台登录界面html模板_科技感登录界面html模板...

    科幻后台登录界面html模板 原始HTML+CSS+JS页面设计,这是一个不错的登录网页制作,画面精明,非常适合初学者学习使用. 作品介绍 1.网页作品简介方面 :蓝色科技风格后台登录框,科幻的网站后 ...

最新文章

  1. linux receive函数,Linux网络 - 数据包的接收过程
  2. 分布式系统的Raft算法——在失联阶段这个老Leader的任何更新都不能算commit,都回滚,接受新的Leader的新的更新 意味着还是可能丢数据!!!...
  3. 网站推广必备手册:SEO教程:搜索引擎优化入门与进阶(第2版)
  4. c语言flappy bird代码,Flappy bird源代码(略吊)
  5. Exchange 2007 邮箱设置
  6. 让wordpress判断是电脑端浏览还是移动端浏览
  7. 使用docker部署redis中间件
  8. CAPL脚本如何实现TCP Socket通信
  9. 08 计算机视觉-opencv直方图与傅里叶变换
  10. 零基础用阿里云服务器搭建网站的步骤
  11. conime.exe
  12. 学习Hibernate框架笔记-第1天
  13. mysql计算增长率
  14. ​九月简报 | Coinversation先行版DEX——Kaco上线碎片化,TVL最高突破1000w美金
  15. 字节跳动 校招薪资曝光,老员工被倒挂疯了~
  16. 屏蔽宽带运营商的弹窗广告
  17. 详解vue路由传参的三种方式
  18. Xilinx 7系列FPGA config设计文档
  19. pr002 导出清晰度降低解决方法
  20. Ubiquitous Computing / Pervasive Computing

热门文章

  1. Javascript对象数组排序
  2. 百度官方wormHole后门检测记录(转)
  3. 用RDA方式同步SQLCE与SQL SERVER数据库
  4. 利润百倍的暴利行业?
  5. 晕!!汗颜!java排序大集合
  6. sqldependency 实现原理_2020阿图什方形摇摆筛安装原理
  7. Java—以当前系统时间生成随机数
  8. 谁用光了磁盘?Docker System命令详解
  9. MySQL数据库无法启动的简单排错
  10. 利用hexo搭建一个只属于你自己的博客