首页 编程教程正文

新浪微博模拟登录 支持手动处理验证码

piaodoo 编程教程 2020-02-22 22:15:11 1312 0 python教程

本文来源吾爱破解论坛

本帖最后由 天空宫阙 于 2020-2-13 22:05 编辑

介绍对于爬取少量的微博信息自己手动登录再copy一下cookie是最简单的方式而对于大规模的爬取,需要大量账号的登录,手动登录费时费力,模拟登录就有它的重要意义一般的做法是大量账号的模拟登录并保存cookie形成cookie池,提供爬虫使用

代码参考https://github.com/CharlesPikachu/DecryptLogin/blob/master/DecryptLogin/platforms/weibo.py通过新浪通行证的登录来登录微博https://login.sina.com.cn/signup/signin.php
登录过程1.预登录,向prelogin_url(https://login.sina.com.cn/sso/prelogin.php)发起get请求得到rsa加密的参数    该请求的核心参数    su  为用户名的base64加密    _   时间戳 python模拟 str(int(time.time()*1000))    其他entry,rsakt,client为不变参数
2.登录,向ssologin_url(https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19))发起post请求登录    改请求核心参数    su 为用户名的base64加密    servertime 预登录返回    nonce 预登录返回    rsakv 预登录返回    sp servertime + '\t' +nonce +'\n'+ password 这一串字符(如图)的rsa加密        rsa加密的modules是与请求返回的pubkey,exponent是"10001"(二进制),用PKCS1_v1_5方式填充        rsa的加密可以用 python的RSA库模拟 也可用pycryptodome库模拟,选择PKCS1_v1_5即可

加密的信息.png (157.53 KB, 下载次数: 1)

下载附件  保存到相册

2020-2-13 21:53 上传


3.请求login_url(https://passport.weibo.com/wbsso/login)    需要携带的核心参数ticket, ssosavestate,均为post请求的返回值
完整代码[Python] 纯文本查看 复制代码
""" 
参考https://github.com/CharlesPikachu/DecryptLogin/blob/master/DecryptLogin/platforms/weibo.py
"""
import requests
import base64
import time
import random
# rsa用的是PKCS1_v1_5填充
import rsa
import re
import json
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Cipher import PKCS1_v1_5
from binascii import b2a_hex
from PIL import Image
import warnings
# 过滤警告信息
warnings.filterwarnings('ignore')

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/78.0.3904.108 Safari/537.36'
        }
        self.prelogin_url = 'https://login.sina.com.cn/sso/prelogin.php'
        self.ssologin_url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
        self.pin_url = 'https://login.sina.com.cn/cgi/pin.php'
        self.login_url = 'https://passport.weibo.com/wbsso/login?'
        self.home_url = 'https://weibo.com/u/%s/home'

    def get_prelogin_info(self,username,password):
        """ 请求prelogin_url得到RSA加密的参数 """
        su = base64.b64encode(username.encode())
        su = str(su,'utf-8')
        params = {
            'entry': 'account',
            # 'callback': 'sinaSSOController.preloginCallBack',
            'su': su,
            'rsakt': 'mod',
            'client': 'ssologin.js(v1.4.15)',
            '_': str(int(time.time()*1000))
        }
        # verify=False 不加也可以返回数据
        res = self.session.get(self.prelogin_url, params=params, verify=False)
        return res.json()

    def get_pin(self):
        """ 保存验证码图片 """
        r = int(random.random()*100000000)
        params = {
                        'r': str(r),
                        's': '0',
                }
        response = self.session.get(self.pin_url,params=params)
        if response.status_code ==200:
            with open('pin_img.png','wb') as f:
                f.write(response.content)
                f.close()
                print('had saved Captcha.')
            # Image好像会调用默认的图片查看器打开图片
            I = Image.open('pin_img.png')
            I.show()
            Captcha_value = input('enter the Captcha value:')
            return Captcha_value

    def post_login_data(self,username,password,Captcha_value=None): 
        """ post请求登录 """  
        p = self.get_prelogin_info(username,password)
        
        # 用不同的库实现RSA加密 都可行
        """ RSA库实现 """
        # publickey = rsa.PublicKey(int(p['pubkey'], 16), int('10001', 16))
        # sp = rsa.encrypt((str(p['servertime'])+'\t'+p['nonce']+'\n'+password).encode(), publickey)
        
        """ 用pycryptodome库实现 """
        rsa_public_key = RSA.construct((int(p['pubkey'],16),int('10001',16)))
        cipher_rsa = PKCS1_v1_5.new(rsa_public_key)
        sp2 = cipher_rsa.encrypt((str(p['servertime'])+'\t'+p['nonce']+'\n'+password).encode())
        # 返回的二进制数据的十六进制表示
        sp = b2a_hex(sp2)
        data_post = {
            'entry': 'account',
            'gateway': '1',
            'from': '',
            'savestate': '30',
            'useticket': '0',
            'pagerefer': '',
            'vsnf': '1',
            'su': base64.b64encode(username.encode()),
            'service': 'account',
            'servertime': str(int(p['servertime'])+random.randint(1, 20)),
            'nonce':p['nonce'],
            'pwencode': 'rsa2',
            'rsakv': p['rsakv'],
            'sp': sp,
            'sr': '1366*768',
            'encoding': 'UTF-8',
            'cdult': '3',
            'domain': 'sina.com.cn',
            'prelt': '95',
            'returntype': 'TEXT',
        }
        if Captcha_value:
            data_post['door'] = Captcha_value
        res = self.session.post(self.ssologin_url, data=data_post,allow_redirects=False, verify=False)
        if res.status_code==200:
            return res.json()
    
    def check_at_login_url(self,res,username):
        ticket, ssosavestate = re.findall(r'ticket=(.*?)&ssosavestate=(.*?)"', res)[0]
        # 请求login_url
        params = {
                    'ticket': ticket,
                    'ssosavestate': str(ssosavestate),
                    'callback': 'sinaSSOController.doCrossDomainCallBack',
                    'scriptId': 'ssoscript0',
                    'client': 'ssologin.js(v1.4.19)',
                    '_': str(int(time.time() * 1000))
                }
        params = '&'.join(['%s=%s' % (key, value) for key, value in params.items()])
        res = self.session.get(self.login_url+params, verify=False)
        uid = re.findall(r'"uniqueid":"(.*?)"', res.text)[0]
        res = self.session.get(self.home_url % uid, verify=False)
        if '我的首页' in res.text:
            print('[INFO]: Account -> %s, login successfully...' % username)
            infos_return = {'username': username}
            return infos_return, self.session

    
    def login(self,username,password):
        res = self.post_login_data(username,password)
        while True:
            if res['retcode']=='0':
                infos_return,login_session = self.check_at_login_url(json.dumps(res),username)
                if login_session:
                    return login_session
                break
            elif res['retcode']=='101':
                # 用户名或密码不正确
                print(res['reason'])
                break
            elif res['retcode']=='4049':
                # 需要验证码
                print(res['reason'])
                res = self.post_login_data(username,password,self.get_pin())
            elif res['retcode']=='2070':
                # 验证码错误
                print(res['reason'])
                res = self.post_login_data(username,password,self.get_pin())
            else:
                print(res)
                break
        


if __name__ == "__main__":
    t = weibo()
    # t.login('用户名','密码')
    login_session = t.login('','')
    # print(login_session.cookies)
    

py文件下载

https://www.lanzous.com/i9bq9yj
效果示例

示例.png (243.88 KB, 下载次数: 0)

下载附件  保存到相册

2020-2-13 21:51 上传



有验证码的情况这个例子中是手动输入的其他方法是接入打码平台,或者cnn(卷积神经网络)训练模型识别(这是人工智能中计算机视觉的内容,还不会)
如果觉得还可以

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:https://www.piaodoo.com/7975.html

搜索