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实现从url中提取域名的几种方法
Sep 26 Python
Python fileinput模块使用实例
Jun 03 Python
Python连接SQLServer2000的方法详解
Apr 19 Python
python3爬取淘宝信息代码分析
Feb 10 Python
python 删除指定时间间隔之前的文件实例
Apr 24 Python
pandas 把数据写入txt文件每行固定写入一定数量的值方法
Dec 28 Python
Python Web版语音合成实例详解
Jul 16 Python
tensor和numpy的互相转换的实现示例
Aug 02 Python
Win10里python3创建虚拟环境的步骤
Jan 31 Python
pycharm无法导入本地模块的解决方式
Feb 12 Python
python 实现压缩和解压缩的示例
Sep 22 Python
pytorch 两个GPU同时训练的解决方案
Jun 01 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利用COM对象访问SQLServer、Access
2006/10/09 PHP
MySQL连接数超过限制的解决方法
2011/07/17 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
100行PHP代码实现socks5代理服务器
2016/04/28 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
从JavaScript的函数重名看其初始化方式
2007/03/08 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
基于jquery实现的一个选择中国大学的弹框 (数据、步骤、代码)
2012/07/26 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
使用OpenLayers3 添加地图鼠标右键菜单
2015/12/29 Javascript
Vue数据驱动模拟实现2
2017/01/11 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
2017/02/14 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
vue-cli单页应用改成多页应用配置详解
2017/07/14 Javascript
详解jQuery中的isPlainObject()使用方法
2018/02/27 jQuery
vue-router beforeEach跳转路由验证用户登录状态
2018/12/26 Javascript
js打开word文档预览操作示例【不是下载】
2019/05/23 Javascript
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
Vue页面刷新记住页面状态的实现
2019/12/27 Javascript
js和jquery判断数据类型的4种方法总结
2020/08/28 jQuery
Django中日期处理注意事项与自定义时间格式转换详解
2018/08/06 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
如何搭建pytorch环境的方法步骤
2020/05/06 Python
英国排名第一的宠物店:PetPlanet
2020/02/02 全球购物
经典C++面试题一
2016/11/06 面试题
个人找工作求职简历的自我评价
2013/10/20 职场文书
刘胡兰的英雄事迹材料
2014/02/11 职场文书
计算机系统管理员求职信
2014/06/20 职场文书
欢迎领导标语
2014/06/27 职场文书
六一儿童节标语
2014/10/08 职场文书
2014年人事科工作总结
2014/11/19 职场文书
社区植树节活动总结
2015/02/06 职场文书
管理人员岗位职责
2015/02/14 职场文书
idea搭建可运行Servlet的Web项目
2021/06/26 Java/Android
漫改真人电影「萌系男友是燃燃的橘色」公开先导视觉图
2022/03/21 日漫
python图像处理 PIL Image操作实例
2022/04/09 Python