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


Posted in Python onSeptember 12, 2019

微博模拟登录

这是本次爬取的网址:https://weibo.com/

一、请求分析

找到登录的位置,填写用户名密码进行登录操作

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

看看这次请求响应的数据是什么

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

这是响应得到的数据,保存下来

exectime: 8
nonce: "HW9VSX"
pcid: "gz-4ede4c6269a09f5b7a6490f790b4aa944eec"
pubkey: "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443"
retcode: 0
rsakv: "1330428213"
servertime: 1568257059

继续完善登录操作,输入密码,点击登录按钮

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

经过分析呢,发现变化的参数就是sp,nonce,servetimeservetime就是当前的时间戳,我们只需找到其他两个参数的生成方法就好了。对了su这个参数是通过base64加密生成的

二、找到sp,nonce的加密方式

这次就不通过search关键字去找加密位置了

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

找到调用函数的位置,打上断点,再进行登录操作

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

经过js代码流程调试分析,最终我们找到了加密的位置

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

简单介绍下怎么调试js代码

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

找到sp,nonce的位置,通过python代码去实现它的加密方式

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

sp它是通过rsa加密方式,加密生成的。rsa的具体用法可以通过百度找到。或者通过sha1加密生成。至于me.rsaPubkey他怎么得到的,他就是我们还没有点击登录前,就发了一个请求,那个请求的响应数据就有它。如果你测试的次数多了的话,会发现这个值它是固定下来的。所以我们也可以直接去用,不用请求获取。

nonce:它呢也出现过在未点击登录前的那个请求响应的数据中,但是呢,我们点了几次登录,都未发现这个请求了。nonce的值每次还不一样。所以它肯定是本地js文件的某个函数生成,不用请求服务器获取。我们在这里找到了nonce的生成函数

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

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

import random
import rsa
import hashlib
from binascii import b2a_hex

def get_nonce(n):
  result = ""
  random_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  for i in range(n):
    index = random.randint(0, len(random_str) - 1)
    result += random_str[index]
  return result


def get_sp_rsa(password, servertime, nonce):
  key = "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443"
  pubkey = rsa.PublicKey(int(key, 16), int("10001", 16))
  res = rsa.encrypt(bytes("" + "\t".join([servertime, nonce]) + "\n" + password,encoding="utf-8"), pubkey)
  return b2a_hex(res)


def get_sp_sha1(password, servertime, nonce):
  res = hashlib.sha1(bytes("" + hashlib.sha1(bytes(hashlib.sha1(bytes(password, encoding="utf-8")).hexdigest(),encoding="utf-8")).hexdigest() + servertime + nonce,encoding="utf-8")).hexdigest()
  return res

三、响应数据

请求参数分析的差不多了,这次输入正确的用户名,密码。查看响应的数据的是什么。

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

打开fiddler,然后退出当前账号,重新进行登录操作。fiddler上面就会出现很多请求。找到需要的请求,看看响应内容

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

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

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

这样做,每个响应都会set-cookie。所以照着上面的流程实现,标识登录的cookie肯定能得到。之后的话,只要带上这个cookie去做其他操作就行了。

最后附上代码

import requests, random, time, rsa, hashlib, base64, re, json
from binascii import b2a_hex
class WeiBo:
  def __init__(self):
    self.session = requests.Session()
    self.headers = {
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
    }
  def login(self, account, password):
    api = "https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)"
    nonce = self._get_nonce()
    servertime = self._get_now_time()
    sp = self._get_sp_rsa(password, servertime, nonce)
    su = self._get_su(account)
    data = {
      "entry": "weibo",
      "gateway": "1",
      "from": "",
      "savestate": "7",
      "qrcode_flag": "false",
      "useticket": "1",
      "pagerefer": "https://login.sina.com.cn/crossdomain2.php?action=logout&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogout%3Fr%3Dhttps%253A%252F%252Fweibo.com%26returntype%3D1",
      "vsnf": "1",
      "su": su,
      "service": "miniblog",
      "servertime": servertime,
      "nonce": nonce,
      "pwencode": "rsa2",
      "rsakv": "1330428213",
      "sp": sp,
      "sr": "1920*1080",
      "encoding": "UTF - 8",
      "prelt": "149",
      "url": "https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
      "returntype": "META",
    }
    headers = self.headers.copy()
    headers.update({
      "Host": "login.sina.com.cn",
      "Origin": "https://weibo.com",
      "Referer": "https://weibo.com/"
    })
    response = self.session.post(api, headers=headers, data=data, allow_redirects=False)
    search_result = self._re_search("location.replace\(\"(.*?)\"", response.text)
    redirct_url = search_result and search_result.group(1)
    if not redirct_url:
      raise Exception("重定向url获取失败")
    response = self.session.get(redirct_url, headers=headers.update({
      "Referer": "https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)"
    }), allow_redirects=False)
    search_result = self._re_search('"arrURL":(.*?)}', response.text)
    redirct_urls = search_result and search_result.group(1)
    if not redirct_urls:
      raise Exception("重定向url获取失败")
    redirct_url_list = json.loads(redirct_urls)
    userId = ""
    for url in redirct_url_list:
      response = self.session.get(url, headers=self.headers)
      if url.startswith("https://passport.weibo.com/wbsso/login"):
        userId = self._re_search('"uniqueid":"(.*?)"', response.text).group(1)
    if not userId:
      raise Exception("userId获取失败")
    user_details_url = "https://weibo.com/u/{}/home?wvr=5&lf=reg".format(userId)
    response = self.session.get(user_details_url, headers={
      "Referer": "https://weibo.com/",
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
    })
    if self._re_search(userId, response.text):
      print("登录成功")
      print(self.session.cookies)
    else:
      print("登录失败")
  def _get_nonce(self):
    nonce = ""
    random_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    for i in range(5):
      index = random.randint(0, len(random_str) - 1)
      nonce += random_str[index]
    return nonce
  def _get_now_time(self):
    return str(int(time.time()))
  def _get_sp_rsa(self, password, servertime, nonce):
    key = "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443"
    pubkey = rsa.PublicKey(int(key, 16), int("10001", 16))
    res = rsa.encrypt(bytes("" + "\t".join([servertime, nonce]) + "\n" + password, encoding="utf-8"), pubkey)
    return b2a_hex(res)
  def _get_sp_sha1(self, password, servertime, nonce):
    res = hashlib.sha1(bytes("" + hashlib.sha1(bytes(hashlib.sha1(bytes(password, encoding="utf-8")).hexdigest(),
                             encoding="utf-8")).hexdigest() + servertime + nonce,
                 encoding="utf-8")).hexdigest()
    return res
  def _get_su(self, account):
    return str(base64.b64encode(bytes(account, encoding="utf-8")), encoding="utf-8")
  def _re_search(self, pattern, html):
    return re.search(pattern, html, re.S)
  def test(self):
    self.login("18716758777", "123456")
if __name__ == '__main__':
  wb = WeiBo()
  wb.test()

总结

以上所述是小编给大家介绍的python爬虫-模拟微博登录功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
使用Python解析JSON数据的基本方法
Oct 15 Python
实例讲解Python中global语句下全局变量的值的修改
Jun 16 Python
django中的setting最佳配置小结
Nov 21 Python
python2.7使用plotly绘制本地散点图和折线图
Apr 02 Python
Python函数参数匹配模型通用规则keyword-only参数详解
Jun 10 Python
PyQT5 QTableView显示绑定数据的实例详解
Jun 25 Python
python开启debug模式的方法
Jun 27 Python
Win10下Python3.7.3安装教程图解
Jul 08 Python
Python替换月份为英文缩写的实现方法
Jul 15 Python
python str字符串转uuid实例
Mar 03 Python
Python3爬虫关于代理池的维护详解
Jul 30 Python
Python爬虫进阶之Beautiful Soup库详解
Apr 29 Python
python设置随机种子实例讲解
Sep 12 #Python
pytest中文文档之编写断言
Sep 12 #Python
python中调试或排错的五种方法示例
Sep 12 #Python
详解Python 中sys.stdin.readline()的用法
Sep 12 #Python
Python3将数据保存为txt文件的方法
Sep 12 #Python
Python3 tkinter 实现文件读取及保存功能
Sep 12 #Python
调试Django时打印SQL语句的日志代码实例
Sep 12 #Python
You might like
PHP sprintf() 函数的应用(定义和用法)
2012/06/29 PHP
PHP入门经历和学习过程分享
2014/04/11 PHP
浅谈discuz密码加密的方式
2014/05/22 PHP
php实例分享之html转为rtf格式
2014/06/02 PHP
ThinkPHP实现将本地文件打包成zip下载
2014/06/26 PHP
smarty半小时快速上手入门教程
2014/10/27 PHP
php绘制一条弧线的方法
2015/01/24 PHP
Yii框架页面渲染操作实例详解
2019/07/19 PHP
Jquery实现自定义窗口随意的拖拽
2014/03/12 Javascript
AngularJS基础教程之简单介绍
2015/09/27 Javascript
jQuery图片旋转插件jQueryRotate.js用法实例(附demo下载)
2016/01/21 Javascript
JavaScript判断表单为空及获取焦点的方法
2016/02/12 Javascript
使用JS轻松实现ionic调用键盘搜索功能(超实用)
2016/09/06 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
vue表单绑定实现多选框和下拉列表的实例
2017/08/12 Javascript
详解利用 Express 托管静态文件的方法
2017/09/18 Javascript
vue组件开发之用户无限添加自定义填写表单的方法
2018/08/28 Javascript
node.js微信小程序配置消息推送的实现
2019/02/13 Javascript
JS实现简易留言板增删功能
2020/02/08 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
2020/11/07 Javascript
[27:53]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS iG
2014/05/26 DOTA
python实现批量改文件名称的方法
2015/05/25 Python
Python设计模式之命令模式简单示例
2018/01/10 Python
Python 判断 有向图 是否有环的实例讲解
2018/02/01 Python
Python数据结构之图的应用示例
2018/05/11 Python
python format 格式化输出方法
2018/07/16 Python
详解Python odoo中嵌入html简单的分页功能
2019/05/29 Python
使用Python的turtle模块画国旗
2019/09/24 Python
django form和field具体方法和属性说明
2020/07/09 Python
详解pycharm2020.1.1专业版安装指南(推荐)
2020/08/07 Python
家用个人磨皮机:Trophy Skin
2017/03/30 全球购物
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
应届毕业生求职信范例分享
2013/12/17 职场文书
卖车协议书范例
2014/09/16 职场文书
初中历史教学反思
2016/02/19 职场文书