今天上课无聊写了一段Python脚本在白嫖GPT方面自给自足

本来后台用 mufeng510/Free-ChatGPT-API: 基于pandora的ChatGPT API,实现了pool token的自动更新 (github.com)的Python脚本好好的,直到…

嗯?

所以用账号和密码自动续期免费逆向API的服务失效了:

原来的Python续期脚本:账号密码—>FakeOpen API获取Access Token (这里失效了) —>获取新的Share Token (失败)—>更新Pool Token失败

不过,也还是有办法的,在FakeOpen登陆网页获取Session Token—>Python脚本:Session Token—>FakeOpen API获取Access Token—>获取新的Share Token—>更新Pool Token

好的,那就… 写个新的Python续期脚本吧!(也借鉴了一下原作者的脚本,谢谢他教会我怎么用Python写POST Request和JSON解析和读写文件保存)

首先看看原本的Python脚本(mufeng510/Free-ChatGPT-API: 基于pandora的ChatGPT API,实现了pool token的自动更新 (github.com)):

# -*- coding: utf-8 -*-


import requests
import random
import string
import time
import re
from os import path
from pandora.openai.auth import Auth0


def run():
    unique_name = generate_random_string(10)

    expires_in = 0
    current_dir = path.dirname(path.abspath(__file__))
    credentials_file = path.join(current_dir, 'credentials.txt')
    tokens_file = path.join(current_dir, 'tokens.txt')
    share_tokens_file = path.join(current_dir, 'share_tokens.txt')
    pool_token_file = path.join(current_dir, 'pool_token.txt')

    # 生成 share token。
    with open(credentials_file, 'r', encoding='utf-8') as f:
        credentials = f.read().split('\n')
    credentials = [credential.split(',', 1) for credential in credentials]

    count = 0
    token_keys = []
    for credential in credentials:
        # 接口有限流。
        sleep_seconds = 15
        print(f"开始休眠 {sleep_seconds} 秒...")
        time.sleep(sleep_seconds)
        print("休眠结束,继续执行后续代码。")
        progress = '{}/{}'.format(credentials.index(credential) + 1, len(credentials))
        if not credential or len(credential) != 2:
            continue

        count += 1
        username, password = credential[0].strip(), credential[1].strip()
        print('Login begin: {}, {}'.format(username, progress))

        token_info = {
            'token': 'None',
            'share_token': 'None',
        }
        token_keys.append(token_info)

        try:
            token_info['token'] = Auth0(username, password).auth(False)
            print('Login success: {}, {}'.format(username, progress))
        except Exception as e:
            err_str = str(e).replace('\n', '').replace('\r', '').strip()
            print('Login failed: {}, {}'.format(username, err_str))
            token_info['token'] = err_str
            continue

        data = {
            'unique_name': unique_name,
            'access_token': token_info['token'],
            'expires_in': expires_in,
        }
        resp = requests.post('https://ai.fakeopen.com/token/register', data=data)
        if resp.status_code == 200:
            token_info['share_token'] = resp.json()['token_key']
            print('share token: {}'.format(token_info['share_token']))
        else:
            err_str = resp.text.replace('\n', '').replace('\r', '').strip()
            print('share token failed: {}'.format(err_str))
            token_info['share_token'] = err_str
            continue

    with open(tokens_file, 'w', encoding='utf-8') as f:
        for token_info in token_keys:
            f.write('{}\n'.format(token_info['token']))

    with open(share_tokens_file, 'w', encoding='utf-8') as f:
        for token_info in token_keys:
            f.write('{}\n'.format(token_info['share_token']))
            
    # 生成 pool token, 如果已有pool token则更新, 没有则新建。
    with open(pool_token_file, 'r', encoding='utf-8') as f:
        pool_token = f.read()
    if(len(pool_token) == 0):
        print("当前不存在pool_token")
    else:
        if(re.compile(r'pk-[0-9a-zA-Z_\-]{43}').match(pool_token)):
            print('已存在: pool token: {}'.format(pool_token))
        else:
            print('pool token: 格式不正确,将重新生成')
            pool_token = ""

    # 从 token_keys 列表中筛选出有效数据
    filtered_tokens = [token_info['share_token'] for token_info in token_keys if re.compile(r'fk-[0-9a-zA-Z_\-]{43}').match(token_info['share_token'])]
    
    with open(pool_token_file, 'w', encoding='utf-8') as f:
        if len(filtered_tokens)==0:
            # 如果没有可用账号,则使用公共pool。
            print('可用账号,请检查后重试')
        else:
            data = {
                'share_tokens': '\n'.join(filtered_tokens),
                'pool_token': pool_token
            }
            resp = requests.post('https://ai.fakeopen.com/pool/update', data=data)
            if resp.status_code == 200:
                result = resp.json()
                print('pool token 更新结果: count:{} pool_token:{}'.format(result['count'],result['pool_token']))
                pool_token = result['pool_token']
                f.write('{}'.format(pool_token))
            else:
                print('pool token 更新失败')
        f.close()


def generate_random_string(length):
    letters = string.ascii_letters
    random_string = ''.join(random.choice(letters) for _ in range(length))
    return random_string

if __name__ == '__main__':
    run()

好像很复杂,但是不要紧,我最近找到了FakeOpen的文档!整体跟着它的POST接口请求然后JSON解析下就可以了。例如发Session Token获取Access Token的POST:

官方文档:Fakeopen API 文档 | FakeOpen Doc

好的,那就趁Professor在review过去12 weeks教了什么让我憔悴的内容的时候写出来吧~

(开源)

# -*- coding: utf-8 -*-
import requests
import json
import random
import string
import time
import re
import os

def generate_random_string(length):
    letters = string.ascii_letters
    random_string = ''.join(random.choice(letters) for _ in range(length))
    return random_string

current_dir = os.path.dirname(os.path.abspath(__file__))
session_file_path = os.path.join(current_dir, 'session.txt')
share_tokens_file = os.path.join(current_dir, 'share_tokens.txt')
pool_token_file = os.path.join(current_dir, 'pool_token.txt')

# 读取 session_keys
with open(session_file_path, 'r', encoding='utf-8') as session_file:
    session_keys_str = session_file.read().strip()

# 检查 session_keys_str 是否存在
if not session_keys_str:
    print("Error: Session keys are missing in session.txt")
else:
    # 用逗号分隔并去除两侧空白字符
    session_keys = [key.strip() for key in session_keys_str.split(',')]

    # 输出分离后的 session_keys (For debugginh
    #print('Key1:\t', session_keys[0])
    #print('Key2:\t', session_keys[1])

#Set up headers for POST (according to FakeOpen Document)
headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
}
    
#Counting number of loops
count = 0

#Create share_tokens list to store Share Tokens as elements
share_tokens = []

#For Loop: If n Session keys are found in session.txt, then n times of exections are proceeded to register n Share Tokens
for i in range(len(session_keys)):
        #Loop + 1
        count += 1

        #1. Use POST to fetch access token by session token (Session Token-->Access Token)
        playload_access_token = {
	    'session_token': session_keys[i]
        }
        
        response_access_token = requests.post('https://ai.fakeopen.com/auth/session', headers=headers , data=playload_access_token)
        
        #200 OK?
        if response_access_token.status_code == 200:
            print('Get Access Token ({}/{})'.format(count,len(session_keys)))
        else:
            err_str = response_access_token.text.replace('\n', '').replace('\r', '').strip()
            print('Failed to get Access Token: {}'.format(err_str))
            continue
        #Debug response_access_token
        #print(response_access_token.text)

        list_access_token = json.loads(response_access_token.text)
        access_token = list_access_token['access_token']
        
        #No need expires_in anymore
        #expires_in = list_access_token['expires_in']

        #Function for generating unique token names
        unique_name = generate_random_string(10)

        #2. Use POST to fetch share token by access token (Access Token-->Share Token)
        playload_share_tokens = {
            'unique_name': unique_name,
            'access_token': access_token
        }

        response_share_tokens = requests.post('https://ai.fakeopen.com/token/register', headers=headers, data=playload_share_tokens)
        
        #200 OK?
        if response_share_tokens.status_code == 200:
            #I put all remaining code here
            list_share_tokens = json.loads(response_share_tokens.text)
            print('Get Share token:{} ({}/{})'.format(list_share_tokens['token_key'],count,len(session_keys)))
            share_tokens.append(list_share_tokens['token_key'])
        else:
            err_str = response_share_tokens.text.replace('\n', '').replace('\r', '').strip()
            print('Failed to get Share Token: {}'.format(err_str))
            continue
#End of for-loop

#Write string to txt
with open(share_tokens_file, 'w', encoding='utf-8') as f:
        #Write share_tokens[0], share_tokens[1], share_tokens[2], ... share_tokens[n-1] elements of Share Tokens into share_tokens.txt
        for token in share_tokens:
            f.write(f"{token}\n") #写入到share_tokens.txt
print('写入share tokens到share_tokens.txt完成')

# 生成 pool token, 如果已有pool token则更新, 没有则新建。
with open(pool_token_file, 'r', encoding='utf-8') as f:
    pool_token = f.read()
    if(len(pool_token) == 0):
        print("当前不存在pool_token")
    else:
        if(re.compile(r'pk-[0-9a-zA-Z_\-]{43}').match(pool_token)):
            print('Already Exist: pool token: {}'.format(pool_token))
        else:
            print('pool token: 格式不正确,将重新生成')
            pool_token = ""
            #How to generate a pool token? Good question. If there is no pool token in pool_token.txt, you can leave it blank. After updating (POST) to the FakeOpen server, the server will generate a new pool token which will be saved in pool_token.txt.         
#3. Use POST to UPDATE pool token by share tokens (Share Token-->Pool Token)
playload_pool = {
    'share_tokens': '\n'.join(share_tokens), #According to FakeOpen Document
    'pool_token': pool_token 
    #This is the pool token which does not change. This token can store bunch of share tokens. Regular Update pool token is necessary.

}

response_pool = requests.post('https://ai.fakeopen.com/pool/update', data=playload_pool)
list_pool_token = json.loads(response_pool.text)

#Display Pool Token (Debugging)
#print('Pool token: ',list_pool_token['pool_token'])

#Write string to txt
with open(pool_token_file, 'w', encoding='utf-8') as f:
            f.write(f"{list_pool_token['pool_token']}\n") #写入到share_tokens.txt
print('写入pool token到pool_token.txt完成')

很好,跑一下看看:

很好,又有API key可以用了,丢去后台:

ChatGPT,启动!

(至于详细的使用教程,有空再讲解吧,懂Python代码的也知道我怎么做了(我的代码程度只是中学生水平),不过有一项注意:session.txt里面存储的session token如果有多余一个的话请用英文逗号分开。P.S. Session Token也挺好,三个月才过期,比Access Token只有十天的期限长太多了。)

其他ChatGPT (ciscohe.cc) 历史更新: chat.ciscohe.cc/update/

End.

Last Edited at 0015hrs on 28/11/2023

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇