關於使用接口方式登陸榛果名宿_學習篇

目標網站前端加密部分

前端js加密

直接上代碼 (登陸速度不錯)

提示: 部分模塊方法未自定義,就沒貼了哈! 不過貼了註釋javascript

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time: 2019/9/17  16:26
# @Author: 餘浪人
# @email: yulangren520@gmail.com
import asyncio
import random
from time import sleep
import requests, base64, json, re
from lxml import etree
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as pk
from pyppeteer import launch
from conf import SpiderConf
from my_mysql import mysql
from my_redis import redis_write, redisCli

session = requests.session()  # 聲明一個session
prefix = SpiderConf.ZG_PREFIX  # 前綴
baseUrl = 'https://passport.meituan.com'
get_url = 'https://passport.meituan.com/account/unitivelogin?service=phoenix&continue=https%3A%2F%2Fwww.zhenguo.com%2Fauth%2Fauthenticated%2F%3Fcontinue%3D%252F&risk_partner=93' # 登陸地址
proxies = {
    "http": "http://113.138.138.244:3617", # 添加代理
}


# 生成加密密碼串
def createPassword(password: str):  # 核心 網站加密前端採用非對稱加密
    public_key = '''-----BEGIN RSA PRIVATE KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRD8YahHualjGxPMzeIWnAqVGMIrWrrkr5L7gw+5XT55iIuYXZYLaUFMTOD9iSyfKlL9mvD3ReUX6Lieph3ajJAPPGEuSHwoj5PN1UiQXK3wzAPKcpwrrA2V4Agu1/RZsyIuzboXgcPexyUYxYUTJH48DeYBGJe2GrYtsmzuIu6QIDAQAB\n-----END RSA PRIVATE KEY-----
    ''' # 目前的公鑰
    pass_word = password.encode(encoding='utf-8')
    rsaKey = RSA.importKey(public_key)
    cipher = pk.new(rsaKey)
    cipherText = base64.b64encode(cipher.encrypt(pass_word)).decode('utf-8')
    return cipherText   # 返回轉換後的密碼串> 用於登陸密碼參數


# 登陸> 正常POST
def baseLogin(account, password, requestCode=None, responseCode=None):  # 常規登陸
    global cookie
    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'} # 頭
    response = session.get(get_url, headers=headers, proxies=proxies) # 獲取登陸頁面
    cookie = requests.utils.dict_from_cookiejar(response.cookies) # 將獲取到的cookie字典化
    html_obj = etree.HTML(response.text)  # 樹對象
    postUrl = baseUrl + ''.join(html_obj.xpath('//form[@id="J-normal-form"]/@action')) # 提取並構造完整url
    csrf = ''.join(html_obj.xpath('//span[@id="csrf"]/text()'))
    headers['Referer'] = get_url
    headers['X-CSRF-Token'] = csrf
    headers['X-Client'] = 'javascript'
    headers['X-Requested-With'] = 'XMLHttpRequest'
    param_data = {
        'ountrycode': '86',
        'email': account,
        'password': password,
        'origin': 'account-login',
        'csrf': csrf,
        'requestCode': requestCode,
        'responseCode': responseCode,  # 須要滑動驗證碼後獲得
    } # 構造登陸參數
    response = session.post(postUrl, data=param_data, headers=headers, proxies=proxies) # 登陸請求
    rawData = response.json() # 接收json響應
    return rawData, response


# 登陸用戶信息獲取
def acquireInfo(resData: dict, account: str, passWord: str):
    data = resData.get('data')
    token = data.get('token')  # 登陸成功token
    _continue = data.get('continue')  # 成功後跳轉地址
    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'
    }
    param_data = {
        'token': token,
        'expire': '0',
        'isdialog': '0',
        'autologin': '0',
        'logintype': 'normal',
    } 
    response = session.post(_continue, data=param_data, headers=headers, proxies=proxies)
    if response.status_code == 200:
        html = etree.HTML(response.text) # 樹對象
        imgUrl = 'https:' + ''.join(html.xpath('//img[@class="navbarDropdown__avatar"]/@src'))  # 頭像地址
        userName = 'https:' + ''.join(html.xpath('//span[@class="navbarDropdown__text"]/text()'))  # 暱稱
        userId = ''.join(''.join(html.xpath('//a[text()="個人主頁"]/@href')).split('/')[-2:-1])
 		# 提取用戶信息
        response = session.get('https://www.zhenguo.com/?logout=1', headers=headers, proxies=proxies)
        if response.status_code == 200:
            cookies = requests.utils.dict_from_cookiejar(response.cookies)
            cookies['time_out'] = 30
            cookies['_userID_'] = userId
            cookies['_userName_'] = userName
            cookies.update(cookie)  # 添加自定義信息,方便獲取及作自動cookie續期
            redis_write(prefix, account, cookies)  # cookie 存入reids
            mysql.autoUser(prefix, account, passWord, '榛果民宿', userImg=imgUrl, nickname=userName)  # 用戶存mysql 用戶作自動登陸
            return True  # 成功返回True
        print('登陸成功, cookie獲取失敗!')
        return
    print('登陸後頁面獲取失敗!')

# 登陸入口
def loginMain(account: str, passWord: str):
    password = createPassword(passWord)
    rawData, response = baseLogin(account, password)
    if 'success' in json.dumps(rawData) and not rawData.get('success'):
        error = rawData.get('error').get('message')  # 錯誤信息
        errorCode = rawData.get('error').get('code')  # 錯誤碼
        if errorCode == 101190:  # 風控驗證 >滑動驗證碼
            responseData = gmailLogin(account, password) # 調用pyppeteer模擬登陸
        elif errorCode == 101157:  # 短信驗證碼
            # dynamicStu = dynamicVerif(rawData)  # 登陸短信驗證時處理
            responseData = {"status": 1, "msg": '動態驗證失敗,請稍後登陸!'}
        elif errorCode == 101005:  # 密碼錯誤
            responseData = {"status": 1, "msg": error}
        elif errorCode == 101144:  # 頻繁提交
            responseData = {"status": 1, "msg": error}
        else:
            responseData = {"status": 1, "msg": '登陸錯誤,請從新登陸!'}
    else:  # 能夠添加其餘錯誤信息處理
        loginStu = acquireInfo(rawData, account, passWord)
        responseData = {"status": 0, "msg": f'{account}: 登陸成功!'} if loginStu else {"status": 1, "msg": f'{account}: 異常,登陸失敗!'}
    return responseData

須要其餘方法能夠郵件或留言喲!html

相關文章
相關標籤/搜索