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制作简单的钢琴程序的教程
Apr 01 Python
详细解读Python的web.py框架下的application.py模块
May 02 Python
Python编程之属性和方法实例详解
May 19 Python
python实现统计代码行数的方法
May 22 Python
Python实现图片转字符画的示例
Aug 22 Python
Python实现PS滤镜特效Marble Filter玻璃条纹扭曲效果示例
Jan 29 Python
Python matplotlib的使用并自定义colormap的方法
Dec 13 Python
Python random模块制作简易的四位数验证码
Feb 01 Python
Python双链表原理与实现方法详解
Feb 22 Python
Python 列表反转显示的四种方法
Nov 16 Python
用python对excel进行操作(读,写,修改)
Dec 25 Python
Django扫码抽奖平台的配置过程详解
Jan 14 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在Web开发领域的优势
2006/10/09 PHP
Http 1.1 Etag 与 Last-Modified提高php效率
2008/01/10 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
2010/10/12 PHP
利用PHP如何实现Socket服务器
2015/09/23 PHP
Zend Framework基于Command命令行建立ZF项目的方法
2017/02/18 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
几个javascript操作word的参考代码
2009/10/26 Javascript
JavaScript 对象模型 执行模型
2009/12/06 Javascript
Javascript中prototype属性实现给内置对象添加新的方法
2015/05/14 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
2016/06/25 Javascript
jquery easyUI中ajax异步校验用户名
2016/08/19 Javascript
JS制作图形验证码实现代码
2020/10/19 Javascript
Angularjs CURD 详解及实例代码
2016/09/14 Javascript
jQuery继承extend用法详解
2016/10/10 Javascript
JS中BOM相关知识点总结(必看篇)
2016/11/22 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
基于JS实现限时抢购倒计时间表代码
2017/05/09 Javascript
JQuery获取元素尺寸、位置及页面滚动事件应用示例
2019/05/14 jQuery
JS使用for in有序获取对象数据
2020/05/19 Javascript
jQuery实现日历效果
2020/09/11 jQuery
[01:02]DOTA2上海特锦赛SHOWOPEN
2016/03/25 DOTA
Python库urllib与urllib2主要区别分析
2014/07/13 Python
python 换位密码算法的实例详解
2017/07/19 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
详解Python异常处理中的Finally else的功能
2017/12/29 Python
django限制匿名用户访问及重定向的方法实例
2018/02/07 Python
Python创建字典的八种方式
2019/02/27 Python
Flask框架工厂函数用法实例分析
2019/05/25 Python
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
低碳生活倡议书
2014/04/14 职场文书
小班上学期幼儿评语
2014/12/30 职场文书
追讨欠款律师函
2015/06/24 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
保护环境建议书作文400字
2015/09/14 职场文书
JS中一些高效的魔法运算符总结
2021/05/06 Javascript
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL