Closed test-black closed 3 years ago
刷新没问题,你看看你.PixivToken.json文件里的token正常么
我用 wiki 那个脚本重新跑了一次 token 丢进去还是报这个错误
v2ray 开了一个10808 端口的 socks5 代理和 10809 的 http 代理
botoy.json文件相较之前没有变化(之前刷新无问题),但出现提到的问题
如果改用 http 代理则无问题
增加了错误提示.你看看报错啥...
不知道什么问题,我这里测试socks和http都正常...
我重新克隆仓库能复现错误,你那边也试试?
# -*- coding: utf-8 -*-
# @Time : 2021/6/20 21:01
# @Author : yuban10703
import hashlib
import json
import random
import re
import sys
import time
import uuid
from datetime import datetime, timedelta
from pathlib import Path
from typing import List
import httpx
from botoy import logger
from botoy.schedule import scheduler
from retrying import retry
from ._proxies import proxies, async_transport, transport
from ..model import FinishSetuData, GetSetuConfig
class PixivToken:
def __init__(self):
self.tokenPath = Path(__file__).parent.parent / ".PixivToken.json"
self.tokendata = {}
self.Client = httpx.Client(proxies=proxies, transport=transport)
def headers(self):
hash_secret = "28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c"
X_Client_Time = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S+08:00")
X_Client_Hash = hashlib.md5(
(X_Client_Time + hash_secret).encode("utf-8")
).hexdigest()
headers = {
"User-Agent": "PixivAndroidApp/5.0.197 (Android 10; Redmi 4)",
"Content-Type": "application/x-www-form-urlencoded",
"Accept-Language": "zh_CN_#Hans",
"App-OS": "android",
"App-OS-Version": "10",
"App-Version": "5.0.197",
"X-Client-Time": X_Client_Time,
"X-Client-Hash": X_Client_Hash,
"Host": "oauth.secure.pixiv.net",
"Accept-Encoding": "gzip",
}
return headers
@retry(stop_max_attempt_number=2, wait_random_max=3000)
def refresh_token(self):
logger.info("尝试刷新Pixiv_token")
data = {
"client_id": "MOBrBDS8blbauoSck0ZfDbtuzpyT",
"client_secret": "lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj",
"grant_type": "refresh_token",
"refresh_token": self.tokendata["refresh_token"],
"device_token": self.tokendata["device_token"]
if "device_token" in self.tokendata.keys()
else uuid.uuid4().hex,
"get_secure_url": "true",
"include_policy": "true",
}
self.tokendata = self.Client.post(
url="https://oauth.secure.pixiv.net/auth/token",
data=data,
headers=self.headers()
).json()
self.tokendata["time"] = time.time()
logger.success("刷新token成功~")
self.saveToken()
def continue_refresh_token(self):
self.refresh_token()
nextTime = int(
self.tokendata["expires_in"] - (time.time() - self.tokendata["time"])
)
self.addJob(nextTime)
return
def saveToken(self):
with open(self.tokenPath, "w", encoding="utf-8") as f:
json.dump(self.tokendata, f, indent=4, ensure_ascii=False)
logger.success("PixivToken已保存到.PixivToken.json")
return
def addJob(self, next_time: int):
logger.info("离下次刷新还有:{}s".format(next_time))
scheduler.add_job(
self.continue_refresh_token,
next_run_time=datetime.now() + timedelta(seconds=next_time - 1),
misfire_grace_time=30,
)
def main(self):
try:
with open(self.tokenPath, "r", encoding="utf-8") as f:
self.tokendata = json.load(f)
logger.success("读取.PixivToken.json成功~")
except Exception as e:
logger.error(".PixivToken.json载入失败,请检查内容并重新启动~\r\n{}".format(e))
sys.exit(0)
if self.tokendata["refresh_token"] == "":
logger.error("PixivToken不存在")
sys.exit(0)
if "time" not in self.tokendata.keys(): # 没time字段就是第一次启动
self.continue_refresh_token()
return
if time.time() - self.tokendata["time"] >= int(
self.tokendata["expires_in"]
): # 停止程序后再次启动时间后的间隔时间超过刷新间隔
self.continue_refresh_token()
return
self.addJob(
int(self.tokendata["expires_in"] - (time.time() - self.tokendata["time"]))
)
pixivToken = PixivToken()
pixivToken.main()
class Pixiv:
def __init__(self, config: GetSetuConfig):
self.config = config
async def get(self): # p站热度榜
tags = self.config.tags.copy()
if self.config.level == 1: # R18 only
tags.append("R-18")
elif self.config.level == 2: # all
if random.choice([True, False]):
tags.append("R-18")
url = "https://app-api.pixiv.net/v1/search/popular-preview/illust"
params = {
"filter": "for_android",
"include_translated_tag_results": "true",
"merge_plain_keyword_results": "true",
"word": " ".join(tags),
"search_target": "partial_match_for_tags",
} # 精确:exact_match_for_tags,部分:partial_match_for_tags
headers = pixivToken.headers()
headers["Host"] = "app-api.pixiv.net"
headers["Authorization"] = "Bearer {}".format(
pixivToken.tokendata["access_token"]
)
try:
async with httpx.AsyncClient(
proxies=proxies, transport=async_transport
) as client:
res = await client.get(url, params=params, headers=headers, timeout=10)
data = res.json()
except Exception as e:
logger.warning("Pixiv热度榜获取失败~:\r\n{}".format(e))
return []
else:
if res.status_code == 200:
data_finally = self.process_data(data)
if len(data_finally) <= self.config.toGetNum - self.config.doneNum:
return data_finally
else:
return random.sample(
self.process_data(data),
self.config.toGetNum - self.config.doneNum,
)
else:
logger.warning("Pixiv热度榜异常:{}\r\n{}".format(res.status_code, data))
return []
def buildOriginalUrl(self, original_url: str, page: int) -> str:
def changePage(matched):
if page > 1:
return "-%s" % (int(matched[0][-1]) + 1)
else:
return ""
msg_changeHost = re.sub(r"//.*/", r"//pixiv.re/", original_url)
return re.sub(r"_p\d+", changePage, msg_changeHost)
def process_data(self, data) -> List[FinishSetuData]:
dataList = []
for d in data["illusts"]:
if d["x_restrict"] == 2: # R18G
continue
if self.config.level == 0 and d["x_restrict"] == 1: # 未开启R18
continue
if d["page_count"] != 1: # 多页画廊
OriginalUrl = d["meta_pages"][0]["image_urls"]["original"]
else:
OriginalUrl = d["meta_single_page"]["original_image_url"]
dataList.append(
FinishSetuData(
title=d["title"],
picID=d["id"],
picWebUrl="www.pixiv.net/artworks/" + str(d["id"]),
page="0",
author=d["user"]["name"],
authorID=d["user"]["id"],
authorWebUrl="www.pixiv.net/users/" + str(d["user"]["id"]),
picOriginalUrl=OriginalUrl,
picLargeUrl=d["image_urls"]["large"].replace("_webp", ""),
picMediumUrl=d["image_urls"]["medium"].replace("_webp", ""),
picOriginalUrl_Msg=self.buildOriginalUrl(
OriginalUrl, d["page_count"]
),
tags=",".join([i["name"] for i in d["tags"]]),
)
)
return dataList
async def main(self) -> List[FinishSetuData]:
if self.config.toGetNum - self.config.doneNum <= 0:
return []
if len(self.config.tags) == 0:
return []
return await self.get()
你用这个替换OPQ-SetuBot\plugins\bot_Setu\APIS\pixiv.py, 再看看报错
Traceback (most recent call last):
File "/home/pi/setubot/Q3/OPQ-SetuBot/bot.py", line 8, in <module>
bot = AsyncBotoy(
File "/home/pi/.local/lib/python3.9/site-packages/botoy/client.py", line 107, in __init__
self.plugMgr.load_plugins()
File "/home/pi/.local/lib/python3.9/site-packages/botoy/plugin.py", line 164, in load_plugins
plugin.load()
File "/home/pi/.local/lib/python3.9/site-packages/botoy/plugin.py", line 67, in load
self.module = importlib.import_module(self.import_path)
File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 850, in exec_module
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu_Cmd/__init__.py", line 4, in <module>
from .command import CMD
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu_Cmd/command.py", line 7, in <module>
from ..bot_Setu.database import getGroupConfig
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/__init__.py", line 8, in <module>
from .setu import Setu
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/setu.py", line 14, in <module>
from .APIS import Lolicon, Pixiv, Yuban
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/APIS/__init__.py", line 5, in <module>
from .pixiv import Pixiv
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/APIS/pixiv.py", line 121, in <module>
pixivToken.main()
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/APIS/pixiv.py", line 108, in main
self.continue_refresh_token()
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/APIS/pixiv.py", line 75, in continue_refresh_token
self.refresh_token()
File "/home/pi/.local/lib/python3.9/site-packages/retrying.py", line 49, in wrapped_f
return Retrying(*dargs, **dkw).call(f, *args, **kw)
File "/home/pi/.local/lib/python3.9/site-packages/retrying.py", line 212, in call
raise attempt.get()
File "/home/pi/.local/lib/python3.9/site-packages/retrying.py", line 247, in get
six.reraise(self.value[0], self.value[1], self.value[2])
File "/home/pi/.local/lib/python3.9/site-packages/six.py", line 719, in reraise
raise value
File "/home/pi/.local/lib/python3.9/site-packages/retrying.py", line 200, in call
attempt = Attempt(fn(*args, **kwargs), attempt_number, False)
File "/home/pi/setubot/Q3/OPQ-SetuBot/plugins/bot_Setu/APIS/pixiv.py", line 65, in refresh_token
self.tokendata = self.Client.post(
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 1095, in post
return self.request(
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 792, in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 877, in send
response = self._send_handling_auth(
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 905, in _send_handling_auth
response = self._send_handling_redirects(
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 942, in _send_handling_redirects
response = self._send_single_request(request)
File "/home/pi/.local/lib/python3.9/site-packages/httpx/_client.py", line 978, in _send_single_request
response = transport.handle_request(request)
TypeError: handle_request() missing 1 required positional argument: 'url'
刚刚更新了下包,复现了,我看看..
pip install httpx==0.19.0
先用旧版本httpx就正常了
问题解决
已配置代理且能访问外网,p 站是不是又改刷新地址了?