async def test1(): client = PixivClient(env=True).start() api = AppPixivAPI(client=client) api.login(refresh_token=_TOKEN) # await api.login(_USERNAME, _PASSWORD) await client.close() print("test1 - finished")
async def get_by_ranking(mode="day", num=3): async with PixivClient(proxy=proxy, timeout=20) as client: aapi = AppPixivAPI(client=client, proxy=proxy) await aapi.login(refresh_token=pixiv_config.pixiv_token) illusts = await aapi.illust_ranking(mode) illusts = illusts["illusts"] random.shuffle(illusts) return illusts[0:num]
async def _test_async_illust_detail(num): async with PixivClient() as client: aapi = AppPixivAPI(client=client) papi = PixivAPI(client=client) await aapi.login(_USERNAME, _PASSWORD) await papi.login(_USERNAME, _PASSWORD) tasks = [asyncio.ensure_future(illust_detail(aapi, i)) for i in range(num)] await asyncio.wait(tasks)
async def _test_async_me_following_works(num): async with PixivClient() as client: aapi = AppPixivAPI(client=client) papi = PixivAPI(client=client) await aapi.login(_USERNAME, _PASSWORD) await papi.login(_USERNAME, _PASSWORD) tasks = [asyncio.ensure_future(me_following_works(papi, i)) for i in range(num)] await asyncio.wait(tasks)
def __init__(self, client: NanoClient, pixiv_client: PixivClient()): self.name = "Pixiv" self.client = client self.aapi = AppPixivAPI(client=pixiv_client.start()) self.day_pool = {} self.day_male_pool = {} self.day_female_pool = {} self.base_url = 'https://www.pixiv.net/en/artworks/' asyncio.ensure_future(self.load_pools_async())
def __init__(self, **kwargs): super().__init__(**kwargs) # forces reauth() to trigger if any method is called: self.last_auth = datetime.datetime.fromtimestamp(0) self.username = "" self.password = "" self.aapi = AppPixivAPI(**kwargs) self.papi = PixivAPI(**kwargs)
async def _test_async_ranking(num): async with PixivClient() as client: aapi = AppPixivAPI(client=client) papi = PixivAPI(client=client) await papi.login(refresh_token=_TOKEN) await aapi.login(refresh_token=_TOKEN) # await aapi.login(_USERNAME, _PASSWORD) # await papi.login(_USERNAME, _PASSWORD) tasks = [asyncio.ensure_future(ranking(papi, i)) for i in range(num)] await asyncio.wait(tasks)
class PixivParser: status = False aapi = AppPixivAPI() id_regex = r"[1-9]\d*" class Config(BaseConfig, config_file="push_config.json"): pixiv_refresh_token: str = str() @classmethod def _check(cls, _attr_name: str, _attr_value: Any) -> Tuple[str, Any]: if _attr_name == "pixiv_refresh_token" and _attr_value == "": logger.exception(f"非法的 refresh_token。如果您不知道这是什么,请查看文档") else: return _attr_name, _attr_value @classmethod def send(self, url: str, classification: str, bot: Bot, target): def origin_link_button(_id: int) -> InlineKeyboardMarkup: return InlineKeyboardMarkup([[ InlineKeyboardButton( text="原链接", url=f"https://www.pixiv.net/artworks/{_id}") ]]) illust_id = int(re.search(pattern=self.id_regex, string=url).group(0)) try: illust = Illust(illust_id, self.Config.pixiv_refresh_token) except IllustInitError: return illust.download() images = illust.get_downloaded_images() if len(images) > 1: bot.send_media_group( chat_id=target, media=[InputMediaPhoto(BytesIO(image)) for image in images]) bot.send_message(text=str(illust), chat_id=target, reply_markup=origin_link_button(illust_id), disable_web_page_preview=True, parse_mode=ParseMode.HTML) else: print(str(illust)) bot.send_photo(photo=BytesIO(images[0]), chat_id=target, caption=str(illust), reply_markup=origin_link_button(illust_id), parse_mode=ParseMode.HTML) logger.info(f"Pixiv: 成功推送 {illust.id}")
async def get_by_search(keyword, num=3): async with PixivClient(proxy=proxy, timeout=20) as client: aapi = AppPixivAPI(client=client, proxy=proxy) await aapi.login(refresh_token=pixiv_config.pixiv_token) illusts = await aapi.search_illust(keyword) illusts = illusts["illusts"] illusts = sorted(illusts, key=lambda i: i["total_bookmarks"], reverse=True) if len(illusts) > num * 3: illusts = illusts[0:int(len(illusts) / 2)] random.shuffle(illusts) return illusts[0:min(num, len(illusts))]
async def to_msg(illusts) -> Message: msg = Message() async with PixivClient(proxy=proxy, timeout=20) as client: aapi = AppPixivAPI(client=client, proxy=proxy) await aapi.login(refresh_token=pixiv_config.pixiv_token) for illust in illusts: try: url: str = illust["image_urls"]["large"] url = url.replace("_webp", "").replace("i.pximg.net", "i.pixiv.re") async with httpx.AsyncClient() as client: resp = await client.get(url, timeout=20) result = resp.content if result: msg.append("{} ({})".format(illust["title"], illust["id"])) msg.append(MessageSegment.image(result)) except Exception as e: logger.warning(f"Error downloading image: {e}") return msg
async def test_pixivpy_async_app_api(): client = PixivClient(env=True) aapi = AppPixivAPI(client=client.start()) # conn = aiohttp.TCPConnector(limit_per_host=30) # session = aiohttp.ClientSession( # connector=conn, # timeout=aiohttp.ClientTimeout(total=10), # trust_env=True, # ) # client.client = session username, password = os.environ['PIXIV_USERNAME'], os.environ['PIXIV_PASS'] # For App Pixiv API await aapi.login(username, password) res = await aapi.illust_ranking("day") illusts = res.get("illusts") print(len(illusts), illusts[0]) await client.close()
async def get_by_id(work_id): async with PixivClient(proxy=proxy, timeout=20) as client: aapi = AppPixivAPI(client=client, proxy=proxy) await aapi.login(refresh_token=pixiv_config.pixiv_token) illust = await aapi.illust_detail(work_id) return illust
def main(): loop = asyncio.get_event_loop() loop.run_until_complete(_main(AppPixivAPI()))
class Illust: aapi = AppPixivAPI(env=True) def __init__(self, illust_id: int, refresh_token:str): async def init_appapi() -> bool: try: await self.aapi.login(refresh_token=refresh_token) except: return False self.aapi.set_accept_language("zh-CN") return True async def get_info() -> bool: try: json_result = await self.aapi.illust_detail(self.id) except: return False info = json_result.illust self.caption = str() if info.caption != "": soup = BeautifulSoup(info.caption, "html.parser") self.caption = "\n" + soup.get_text() self.title = info.title self.author = (info.user.name, info.user.id) self.tags = [(tag.name, tag.translated_name) for tag in info.tags] if info.page_count == 1: self.urls = [info.image_urls.large] self.original_urls = [info.meta_single_page.original_image_url] else: self.urls = [ page.image_urls.large for page in info.meta_pages] self.original_urls = [ page.image_urls.original for page in info.meta_pages] return True loop = asyncio.new_event_loop() login_result = loop.run_until_complete(init_appapi()) loop.close() if not login_result: logger.exception("Pixiv 登录失败") raise LoginError logger.info("Pixiv 登录成功") self.id: int = illust_id self.__images: list = list() loop = asyncio.new_event_loop() get_info_result = loop.run_until_complete(get_info()) loop.close() if not get_info_result: logger.exception("插画信息获取失败") raise GetInfoError def __str__(self): tags_text = str() for tag in self.tags: tags_text = tags_text + \ f"<a href=\"https://www.pixiv.net/tags/{tag[0]}/artworks\">{tag[0]}</a>" if tag[1]: tags_text = tags_text + f" ({tag[1]})" tags_text = tags_text+", " return f"<b>标题:</b>{self.title}\n<b>作者:</b><a href=\"https://www.pixiv.net/users/{self.author[1]}\">{self.author[0]}</a>\n<b>简介:</b>{self.caption}\n<b>标签:</b>{tags_text}" async def __download_single_image(self, url: str, size_hint: str, page_hint: int): try: content, type = await self.aapi.down(url, "https://app-api.pixiv.net/") except: logger.exception(f"{self.id} {size_hint} 第 {page_hint} 张下载错误") raise DownloadError if type is not None and type.find("image") != -1: self.__images.append((page_hint, content)) else: logger.exception(f"{self.id} {size_hint} 第 {page_hint} 张下载错误") raise DownloadError logger.info(f"成功下载 {self.id} {size_hint} 第 {page_hint} 张") def __download_images(self, original: bool = False): page = 0 loop = asyncio.new_event_loop() if not original: urls = self.urls size_hint = "large" else: urls = self.original_urls size_hint = "original" tasks = list() for url in urls: tasks.append(self.__download_single_image(url, size_hint, page)) page = page + 1 try: loop.run_until_complete(asyncio.gather(*tasks, loop=loop)) except DownloadError: pass finally: loop.close() logger.info(f"成功下载 {self.id} 全部 {size_hint} 图片") def download(self): self.__download_images() def download_original(self): self.__download_images(True) def get_downloaded_images(self): if not len(self.__images): return None self.__images.sort(key=lambda elem: elem[0]) return [elem[1] for elem in self.__images[:9]]
class PixivParser: status = False aapi = AppPixivAPI() id_regex = r"[1-9]\d*" class Config(BaseConfig, config_file="push_config.json"): pixiv_username: str = str() pixiv_password: str = str() download_path: Optional[str] = str() @classmethod def _check(cls, _attr_name: str, _attr_value: Any) -> Tuple[str, Any]: if _attr_name == "download_path" and _attr_value == "": logger.info(f"未提供下载路径, 使用 {os.path.dirname(__file__)}/PixivDownload") try: os.mkdir(f"{os.path.dirname(__file__)}/PixivDownload") except FileExistsError: pass except BaseException as exc: logger.exception("下载路径不可用") #sys.exit(1) raise exc return _attr_name, os.path.dirname(__file__) + "/PixivDownload" else: return _attr_name, _attr_value @classmethod @run_async def send(self, url: str, classification: str, bot: Bot, target): async def init_appapi(aapi: AppPixivAPI): try: await aapi.login(username=self.Config.pixiv_username, password=self.Config.pixiv_password) except: logger.exception("Pixiv 登陆失败") return False logger.info("成功登录 Pixiv") aapi.set_accept_language("zh-CN") return True def origin_link(_id: int): return InlineKeyboardMarkup([[InlineKeyboardButton(text="原链接", url=f"https://www.pixiv.net/artworks/{_id}")]]) def parse_tags_text(tags: list) -> str: text = str() for tag in tags: if tag.translated_name: translated_name = f"({tag.translated_name})" else: translated_name = "" text = text + \ f"<a href=\"https://www.pixiv.net/tags/{tag.name}/artworks\">{tag.name}{translated_name}</a> " return text async def download_single_pic(url: str, _id: int, size: str, page: int, aapi: AppPixivAPI): url_basename = os.path.basename(url) extension = os.path.splitext(url_basename)[1] name = f"{_id}_p{page}_{size}{extension}" try: os.mkdir(f"{self.Config.download_path}/{_id}") except FileExistsError: pass await aapi.download(url, path=self.Config.download_path + "/" + str(_id), name=name) logger.info(f"成功下载 {name}") def download_pic(urls: list, _id: int, size: str, aapi: AppPixivAPI): page = 0 loop = asyncio.new_event_loop() tasks = list() for url in urls: tasks.append(download_single_pic(url, _id, size, page, aapi)) # download_single_pic(url, _id, size, page, aapi) page = page + 1 loop.run_until_complete(asyncio.gather(*tasks, loop=loop)) loop.close() logger.info(f"成功下载 {_id} 全部图片") async def parse_illust_info_msg(illust_id: int, aapi: AppPixivAPI): json_result = await aapi.illust_detail(illust_id) info = json_result.illust caption = str() if info.caption != "": soup = BeautifulSoup(info.caption, "html.parser") caption = "\n" + soup.get_text() msg_text = f"<b>标题:</b>{info.title}\n<b>作者:</b><a href=\"https://www.pixiv.net/users/{info.user.id}\">{info.user.name}</a>{caption}\n<b>标签:</b>{parse_tags_text(info.tags)}{classification}" logger.info(msg_text) if info.page_count == 1: illust_urls = [info.image_urls.large] else: illust_urls = [page.image_urls.large for page in info.meta_pages] return illust_urls, illust_id, msg_text loop = asyncio.new_event_loop() login_result = loop.run_until_complete(init_appapi(self.aapi)) loop.close() if not login_result: return illust_id = int(re.search(pattern=self.id_regex, string=url).group(0)) loop = asyncio.new_event_loop() illust_urls, illust_id, msg_text = loop.run_until_complete( parse_illust_info_msg(illust_id, self.aapi)) loop.close() download_pic(illust_urls, illust_id, "large", self.aapi) file_dirs = [self.Config.download_path+f"/{illust_id}/" + filename for filename in os.listdir(self.Config.download_path+f"/{illust_id}")] if len(file_dirs) == 1: bot.send_photo(chat_id=target, photo=open(file_dirs[0], 'rb'), caption=msg_text, reply_markup=origin_link(illust_id), parse_mode=ParseMode.HTML) else: tmp_sub_file_group = list() tmp_size = 0 sub_file_groups = list() for file_dir in file_dirs: if tmp_size + os.path.getsize(file_dir) <= 5242880 and len(tmp_sub_file_group) + 1 <= 10: tmp_sub_file_group.append(InputMediaPhoto(media=open(file_dir, 'rb'), caption=msg_text, parse_mode=ParseMode.HTML)) else: sub_file_groups.append(tmp_sub_file_group) tmp_sub_file_group = [InputMediaPhoto(media=open(file_dir, 'rb'), caption=msg_text, parse_mode=ParseMode.HTML)] tmp_size = os.path.getsize(file_dir) sub_file_groups.append(tmp_sub_file_group) for sub_file_group in sub_file_groups: bot.send_media_group(chat_id=target, media=sub_file_group) bot.send_message(chat_id=target, text=msg_text, reply_markup=origin_link(illust_id), disable_web_page_preview=True, parse_mode=ParseMode.HTML)