折腾人啊,知乎个人回答不行啊.我还莫名其妙的把我的文件替换错了.

#encoding=gbk 
import base64
import hashlib
import hmac
import json
import re
import threading
import time
from http import cookiejar
from urllib.parse import urlencode

import execjs
import requests
from PIL import Image
import 常用
#本来注释了一遍的,结果乱搞,搞掉了.真坑人.
    
用户名=''
密码=''

登录数据= {
    'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
    'grant_type': 'password',
    'source': 'com.zhihu.web',
    'username': '',
    'password': '',
    'lang': 'en',
    'ref_source': 'other_https://www.zhihu.com/signin?next=%2F',
    'utm_source': ''
}
会话 = requests.session()
会话.headers = {
    'accept-encoding': 'gzip, deflate, br',
    'Host': 'www.zhihu.com',
    'Referer': 'https://www.zhihu.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                  '(KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
}
会话.cookies = cookiejar.LWPCookieJar(filename='./cookies.txt')

def 登录(语言: str = 'en', 冲: bool = True):
    global 登录数据
    ifand 加载冲():
        print('读取 Cookies 文件')
        if 检查登录():
            print('登录成功')
            return True
        print('Cookies 已过期')

    检查密码()
    登录数据.update({
        'username': 用户名,
        'password': 密码,
        'lang': 语言
    })#要有用户,密码,语言

    戳 = int(time.time() * 1000)
    登录数据.update({
        'captcha': 取码(登录数据['lang']),
        'timestamp': 戳,
        'signature': 取签名(戳)
    })#要有验证码,时间戳,签名

    h = 会话.headers.copy()
    h.update({
        'content-type': 'application/x-www-form-urlencoded',
        'x-zse-83': '3_2.0',
        'x-xsrftoken': 取跨()
    })
    data = 加密(登录数据)
    登录口 = 'https://www.zhihu.com/api/v3/oauth/sign_in'
    resp = 会话.post(登录口, data=data, headers=h)
    if 'error' in resp.text:
        print(json.loads(resp.text)['error'])
    if 检查登录():
        print('登录成功')
        return True
    print('登录失败')
    return False

def 加载冲():
    try:
        会话.cookies.load(ignore_discard=True)
        return True
    except FileNotFoundError:
        return False

def 检查登录():
    d= 'https://www.zhihu.com/signup'
    resp = 会话.get(d, allow_redirects=False)
    if resp.status_code == 302:
        会话.cookies.save()
        return True
    return False

def 取跨():
    会话.get('https://www.zhihu.com/', allow_redirects=False)
    for c in 会话.cookies:
        if c.name == '_xsrf':
            return c.value
    raise AssertionError('获取 xsrf 失败')

def 取码(lang: str):
    if lang == 'cn':
        api = 'https://www.zhihu.com/api/v3/oauth/captcha?lang=cn'
    else:
        api = 'https://www.zhihu.com/api/v3/oauth/captcha?lang=en'
    resp = 会话.get(api)
    显示 = re.search(r'true', resp.text)

    if 显示:
        p= 会话.put(api)
        数格 = json.loads(p.text)
        图64 = 数格['img_base64'].replace(r'\n', '')
        with open('./captcha.jpg', 'wb') as f:
            f.write(base64.b64decode(图64))
        img = Image.open('./captcha.jpg')
        if lang == 'cn':
            import matplotlib.pyplot as plt
            plt.imshow(img)
            print('点击所有倒立的汉字,在命令行中按回车提交')
            points = plt.ginput(7)
            capt = json.dumps({'img_size': [200, 44],
                               'input_points': [[i[0] / 2, i[1] / 2] for i in points]})
        else:
            img_thread = threading.Thread(target=img.show, daemon=True)
            img_thread.start()
            # 这里可自行集成验证码识别模块
            capt = input('请输入图片里的验证码:')
        # 这里必须先把参数 POST 验证码接口
        #要单独提交这里
        会话.post(api, data={'input_text': capt})
        return capt
    return ''

def 取签名(戳: int or str):
    ha = hmac.new(b'd1b964811afb40118a12068ff74a12f4', digestmod=hashlib.sha1)
    g=登录数据['grant_type']
    c=登录数据['client_id']
    s=登录数据['source']
    ha.update(bytes((g+c+s+str(戳)), 'utf-8'))
    return ha.hexdigest()

def 检查密码():
    global 用户名,密码
    if not 用户名:
        用户名 = input('请输入手机号:')
    if 用户名.isdigit() and '+86' not in 用户名:
        用户名 = '+86' + 用户名
    if not 密码:
        密码 = input('请输入密码:')

def 加密(form_data: dict):
    with open('./encrypt.js') as f:
        js = execjs.compile(f.read())
        return js.call('b', urlencode(form_data))

登录(语言='en', 冲=True)

改了下,原来的因为使用了缓存,所以后面的没试.动态语言,最后才会发现问题.折腾人.

posted @   zjh6  阅读(13)  评论(0编辑  收藏  举报  
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示