Python爬虫破解登陆哔哩哔哩的方法


Posted in Python onNovember 17, 2020

写在前面

作为一名找不到工作的爬虫菜鸡人士来说,登陆这一块肯定是个比较大的难题。
 从今天开始准备一点点对大型网站进行逐个登陆破解。加深自己爬虫水平。

环境搭建

  • Python 3.7.7环境,Mac电脑测试
  • Python内置库
  • 第三方库:rsa、urllib、requests

PC端登陆

全部代码:

'''PC登录哔哩哔哩'''
class Bilibili_For_PC():
  def __init__(self, **kwargs):
    for key, value in kwargs.items(): setattr(self, key, value)
    self.session = requests.Session()
    self.__initialize()
  '''登录函数'''
  def login(self, username, password, crack_captcha_func=None, **kwargs):
    # 若参数中给入代理,则设置
    self.session.proxies.update(kwargs.get('proxies', {}))
    # 是否需要验证码
    is_need_captcha = False
    while True:
      # 需要验证码
      if is_need_captcha:
        captcha_img = self.session.get(self.captcha_url, headers=self.captcha_headers).content
        data = {'image': base64.b64encode(captcha_img).decode('utf-8')}
        captcha = self.session.post(self.crack_captcha_url, json=data).json()['message']
      # 获得key值
      appkey = '1d8b6e7d45233436'
      data = {
            'appkey': appkey,
            'sign': self.__calcSign('appkey={}'.format(appkey))
          }
      response = self.session.post(self.getkey_url, data=data)
      response_json = response.json()
      key_hash = response_json['data']['hash']
      pub_key = rsa.PublicKey.load_pkcs1_openssl_pem(response_json['data']['key'].encode('utf-8'))
      # 模拟登录
      if is_need_captcha:
        data = "access_key=&actionKey=appkey&appkey={}&build=6040500&captcha={}&challenge=&channel=bili&cookies=&device=pc&password={}&permission=ALL&seccode=&subid=1&ts={}&username={}&validate=" \
            .format(appkey, captcha, urllib.parse.quote_plus(base64.b64encode(rsa.encrypt('{}{}'.format(key_hash, password).encode(), pub_key))), int(time.time()), urllib.parse.quote_plus(username))
      else:
        data = "access_key=&actionKey=appkey&appkey={}&build=6040500&captcha=&challenge=&channel=bili&cookies=&device=pc&password={}&permission=ALL&seccode=&subid=1&ts={}&username={}&validate=" \
            .format(appkey, urllib.parse.quote_plus(base64.b64encode(rsa.encrypt('{}{}'.format(key_hash, password).encode(), pub_key))), int(time.time()), urllib.parse.quote_plus(username))
      data = "{}&sign={}".format(data, self.__calcSign(data))
      response = self.session.post(self.login_url, data=data, headers=self.login_headers)
      response_json = response.json()
      # 不需要验证码, 登录成功
      if response_json['code'] == 0 and response_json['data']['status'] == 0:
        for cookie in response_json['data']['cookie_info']['cookies']:
          self.session.cookies.set(cookie['name'], cookie['value'], domain='.bilibili')
        print('[INFO]: Account -> %s, login successfully' % username)
        infos_return = {'username': username}
        infos_return.update(response_json)
        return infos_return, self.session
      # 需要识别验证码
      elif response_json['code'] == -105:
        is_need_captcha = True
      # 账号密码错误
      elif response_json['code'] == -629:
        raise RuntimeError('Account -> %s, fail to login, username or password error' % username)
      # 其他错误
      else:
        raise RuntimeError(response_json.get('message'))
  '''计算sign值'''
  def __calcSign(self, param, salt="560c52ccd288fed045859ed18bffd973"):
    sign = hashlib.md5('{}{}'.format(param, salt).encode('utf-8'))
    return sign.hexdigest()
  '''初始化'''
  def __initialize(self):
   # 登陆请求头
    self.login_headers = {'Content-type': 'application/x-www-form-urlencoded'}
    # 破解验证码请求头
    self.captcha_headers = {'Host': 'passport.bilibili.com'}
    # 获取key密钥URL
    self.getkey_url = 'https://passport.bilibili.com/api/oauth2/getKey'
    # 获取登陆URL
    self.login_url = 'https://passport.bilibili.com/api/v3/oauth2/login'
    # 获取验证码URL
    self.captcha_url = 'https://passport.bilibili.com/captcha'
    # 破解网站来自: https://github.com/Hsury/Bilibili-Toolkit
    # 破解验证码URL
    self.crack_captcha_url = 'https://bili.dev:2233/captcha'
    # 请求头都得加这个
    self.session.headers.update({'User-Agent': "Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)"})

移动端登陆

移动端与PC端类似,网址URL差异以及请求头差异。在此不过多介绍。
 全部代码:

'''移动端登录B站'''
class Bilibili_For_Mobile():
  def __init__(self, **kwargs):
    for key, value in kwargs.items(): setattr(self, key, value)
    self.session = requests.Session()
    self.__initialize()
  '''登录函数'''
  def login(self, username, password, crack_captcha_func=None, **kwargs):
    self.session.proxies.update(kwargs.get('proxies', {}))
    # 是否需要验证码
    is_need_captcha = False
    while True:
      # 需要验证码
      if is_need_captcha:
        captcha_img = self.session.get(self.captcha_url, headers=self.captcha_headers).content
        data = {'image': base64.b64encode(captcha_img).decode('utf-8')}
        captcha = self.session.post(self.crack_captcha_url, json=data).json()['message']
      # 获得key值
      appkey = 'bca7e84c2d947ac6'
      data = {
            'appkey': appkey,
            'sign': self.__calcSign('appkey={}'.format(appkey))
          }
      response = self.session.post(self.getkey_url, data=data)
      response_json = response.json()
      key_hash = response_json['data']['hash']
      pub_key = rsa.PublicKey.load_pkcs1_openssl_pem(response_json['data']['key'].encode('utf-8'))
      # 模拟登录
      if is_need_captcha:
        data = "access_key=&actionKey=appkey&appkey={}&build=6040500&captcha={}&challenge=&channel=bili&cookies=&device=phone&mobi_app=android&password={}&permission=ALL&platform=android&seccode=&subid=1&ts={}&username={}&validate=" \
            .format(appkey, captcha, urllib.parse.quote_plus(base64.b64encode(rsa.encrypt('{}{}'.format(key_hash, password).encode(), pub_key))), int(time.time()), urllib.parse.quote_plus(username))
      else:
        data = "access_key=&actionKey=appkey&appkey={}&build=6040500&captcha=&challenge=&channel=bili&cookies=&device=phone&mobi_app=android&password={}&permission=ALL&platform=android&seccode=&subid=1&ts={}&username={}&validate=" \
            .format(appkey, urllib.parse.quote_plus(base64.b64encode(rsa.encrypt('{}{}'.format(key_hash, password).encode(), pub_key))), int(time.time()), urllib.parse.quote_plus(username))
      data = "{}&sign={}".format(data, self.__calcSign(data))
      response = self.session.post(self.login_url, data=data, headers=self.login_headers)
      response_json = response.json()
      # 不需要验证码, 登录成功
      if response_json['code'] == 0 and response_json['data']['status'] == 0:
        for cookie in response_json['data']['cookie_info']['cookies']:
          self.session.cookies.set(cookie['name'], cookie['value'], domain='.bilibili')
        print('[INFO]: Account -> %s, login successfully' % username)
        infos_return = {'username': username}
        infos_return.update(response_json)
        return infos_return, self.session
      # 需要识别验证码
      elif response_json['code'] == -105:
        is_need_captcha = True
      # 账号密码错误
      elif response_json['code'] == -629:
        raise RuntimeError('Account -> %s, fail to login, username or password error' % username)
      # 其他错误
      else:
        raise RuntimeError(response_json.get('message'))
  '''计算sign值'''
  def __calcSign(self, param, salt="60698ba2f68e01ce44738920a0ffe768"):
    sign = hashlib.md5('{}{}'.format(param, salt).encode('utf-8'))
    return sign.hexdigest()
  '''初始化'''
  def __initialize(self):
    self.login_headers = {
                'Content-type': 'application/x-www-form-urlencoded'
              }
    self.captcha_headers = {
                'Host': 'passport.bilibili.com'
              }
    self.getkey_url = 'https://passport.bilibili.com/api/oauth2/getKey'
    self.login_url = 'https://passport.bilibili.com/api/v3/oauth2/login'
    self.captcha_url = 'https://passport.bilibili.com/captcha'
    # 破解网站来自: https://github.com/Hsury/Bilibili-Toolkit
    self.crack_captcha_url = 'https://bili.dev:2233/captcha'
    self.session.headers.update({'User-Agent': "Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)"})

到此这篇关于Python爬虫破解登陆哔哩哔哩的方法的文章就介绍到这了,更多相关Python爬虫破解登陆内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python入门篇之面向对象
Oct 20 Python
在Python下利用OpenCV来旋转图像的教程
Apr 16 Python
Python编程pygal绘图实例之XY线
Dec 09 Python
python3解析库pyquery的深入讲解
Jun 26 Python
python实现简单的文字识别
Nov 27 Python
python @classmethod 的使用场合详解
Aug 23 Python
Python笔记之观察者模式
Nov 20 Python
python使用pip安装SciPy、SymPy、matplotlib教程
Nov 20 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
Feb 25 Python
基于python实现对文件进行切分行
Apr 26 Python
利用Python如何实时检测自身内存占用
May 09 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
May 22 Python
appium+python自动化配置(adk、jdk、node.js)
Nov 17 #Python
python调用百度API实现人脸识别
Nov 17 #Python
详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强
Nov 17 #Python
详解Pytorch显存动态分配规律探索
Nov 17 #Python
Python调用ffmpeg开源视频处理库,批量处理视频
Nov 16 #Python
python tkinter实现连连看游戏
Nov 16 #Python
详解python os.path.exists判断文件或文件夹是否存在
Nov 16 #Python
You might like
十天学会php之第五天
2006/10/09 PHP
?算你??的 PHP 程式大小
2006/12/06 PHP
php 将json格式数据转换成数组的方法
2018/08/21 PHP
再谈IE中Flash控件的自动激活 ObjectWrap
2007/03/09 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
js正则表达式匹配数字字母下划线等
2015/04/14 Javascript
浅谈jquery.fn.extend与jquery.extend区别
2015/07/13 Javascript
js实现仿爱微网两级导航菜单效果代码
2015/08/31 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
使用jQuery调用XML实现无刷新即时聊天
2016/08/07 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
2016/12/08 Javascript
BootStrap 弹出层代码
2017/02/09 Javascript
原生js实现验证码功能
2017/03/16 Javascript
浅谈事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流
2017/07/22 jQuery
vue.js实现插入数值与表达式的方法分析
2018/07/06 Javascript
微信小程序textarea层级过高的解决方法
2019/03/04 Javascript
在vue中使用image-webpack-loader实例
2020/11/12 Javascript
Linux环境下MySQL-python安装过程分享
2015/02/02 Python
探究数组排序提升Python程序的循环的运行效率的原因
2015/04/01 Python
Python扫描IP段查看指定端口是否开放的方法
2015/06/09 Python
python非递归全排列实现方法
2017/04/10 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
python多线程下信号处理程序示例
2019/05/31 Python
python实现月食效果实例代码
2019/06/18 Python
Python中注释(多行注释和单行注释)的用法实例
2019/08/28 Python
python爬虫 Pyppeteer使用方法解析
2019/09/28 Python
基于CSS3特效之动画:animation的应用
2013/05/09 HTML / CSS
const和static readonly区别
2013/05/20 面试题
《社戏》教学反思
2014/04/15 职场文书
岗位说明书怎么写
2014/07/30 职场文书
党的群众路线调研报告
2014/11/03 职场文书
2014年施工员工作总结
2014/11/18 职场文书
婚前保证书范文
2015/02/28 职场文书
公司周年庆寄语
2019/06/21 职场文书
导游词之青城山景区
2019/09/27 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python