Home

Awesome

PixivPy-Async

PyPI version

Async Pixiv API for Python 3(with Auth supported)

PixivPy-Async is an async Python 3 library of Pixiv API(with Auth supported).

Source: https://github.com/Mikubill/pixivpy-async

Based on PixivPy: https://github.com/upbit/pixivpy

中文说明

Note

Install

pip install pixivpy-async

Or install with socks proxy support:

pip install pixivpy-async[socks]

Import Package

Import async pixivpy:

from pixivpy_async import *

...or sync pixivpy(Sync Support):

from pixivpy_async.sync import *

API Init

# Use Context Manager (Recommended)
async with PixivClient() as client:
    aapi = AppPixivAPI(client=client)
    # Doing stuff...
    
# Or
client = PixivClient()
aapi = AppPixivAPI(client=client.start())
# Doing stuff...
await client.close()

# Or Following Standard Usage
aapi = AppPixivAPI()

# 绕过 SNI 检测
aapi = AppPixivAPI(bypass=True)

Login

# For App Pixiv API
await aapi.login(username, password)

# Or
await aapi.login(refresh_token=TOKEN)

# Login with oauth (manually)
await aapi.login_web()

Proxy

The default is not to use any proxy (ignoring environment variables).

Use environment variables, automatically recognized by aiohttp (not support socks5)

...PixivClient(env=True)
...AppPixivAPI(env=True)

Specify the proxy address, support socks5/socks4/http (not support https)

If use the socks5/socks4 proxy, make sure the package is installed with socks proxy support.

...PixivClient(proxy="socks5://127.0.0.1:8080")
...AppPixivAPI(proxy="socks5://127.0.0.1:8080")

If the package is not installed with socks proxy support, and your application runs on Windows, please make sure that event loop uses the policy asyncio.WindowsSelectorEventLoopPolicy before loop runs. #issue4536

import asyncio

if __name__ == '__main__':
    policy = asyncio.WindowsSelectorEventLoopPolicy()
    asyncio.set_event_loop_policy(policy)
    asyncio.run(...)    # use pixivpy_async with socks proxy

Note that env will be ignored when a proxy is specified.

Doing stuff

await aapi.illust_detail(59580629)
await aapi.illust_comments(59580629)
await aapi.ugoira_metadata(51815717)

await aapi.illust_recommended(bookmark_illust_ids=[59580629])
aapi.parse_qs(json_result.next_url) # page down in some case
await aapi.illust_recommended(**next_qs)
await aapi.illust_related(59580629)
await aapi.user_detail(275527)
await aapi.user_illusts(275527)
await aapi.user_bookmarks_illust(2088434)
await aapi.user_following(7314824)
await aapi.user_follower(275527)
await aapi.user_mypixiv(275527)
await aapi.user_related(...)
await aapi.user_follow_add(...)
await aapi.user_follow_del(...)
await aapi.user_bookmark_tags_illust(...)
await aapi.user_list(...)
await aapi.search_user(...)
await aapi.trending_tags_illust()
await aapi.search_illust(first_tag, search_target='partial_match_for_tags')
await aapi.illust_ranking('day_male')
await aapi.illust_follow(req_auth=True)
await aapi.illust_recommended(req_auth=True)
await aapi.illust_ranking('day', date='2016-08-01')
await aapi.illust_bookmark_detail(...)
await aapi.illust_bookmark_add(...)
await aapi.illust_bookmark_delete(...)
await aapi.download(image_url, path=directory, name=name)
await aapi.search_novel(...)
await aapi.user_novels(...)
await aapi.novel_series(...)
await aapi.novel_detail(...)
await aapi.novel_text(...)

# papi is deprecated
await papi.works(46363414)
await papi.users(1184799)
await papi.me_feeds(show_r18=0)
await papi.me_favorite_works(publicity='private')
await papi.me_following_works()
await papi.me_following()
await papi.users_works(1184799)
await papi.users_favorite_works(1184799)
await papi.users_feeds(1184799, show_r18=0)
await papi.users_following(4102577)
await papi.ranking('illust', 'weekly', 1)
await papi.ranking(ranking_type='all', mode='daily', page=1, date='2015-05-01')

await papi.search_works("五航戦 姉妹", page=1, mode='text')
await papi.latest_works()

Nest steps

Read docs for more information

Read demos for more usage

Sync support

(Inspired by telethon)

The moment you import any of these:

from pixivpy_async import sync, ...
# or
from pixivpy_async.sync import ...
# or
import pixivpy_async.sync

The sync module rewrites most async def methods in pixivpy_async to something similar to this:

def new_method():
    result = original_method()
    if loop.is_running():
        # the loop is already running, return the await-able to the user
        return result
    else:
        # the loop is not running yet, so we can run it for the user
        return loop.run_until_complete(result)

That means you can do thing like this:

aapi = AppPixivAPI()
aapi.login(username, password)

Update

Performance Testing

Warning: The rate limit was hit multiple times during the test, so the result may not be informative.

Script: https://github.com/Mikubill/pixivpy-async/blob/master/Perf.py

MethodSync(10,sg)Async(10,sg)Sync(200,sg)Async(200,sg)
illust_detail1.12090.864131.70412.4580
illust_ranking1.06970.793628.45392.0693
user_illusts0.88240.750528.39811.8199
user_detail0.96280.755028.30551.7738
ugoira_metadata0.85090.745929.55662.2331
works1.12040.891232.20682.8513
me_following_works1.12530.784539.31422.2785
ranking1.09460.794439.65092.6548
latest_works1.04830.866736.19922.5066
MethodSync(500,jp)Async(500,jp)
illust_detail6.21780.6400
illust_ranking6.40460.6119
user_illusts7.60931.5266
user_detail6.67590.5952
ugoira_metadata6.51550.7577
works13.30740.8619
me_following_works24.26932.0835
ranking21.41193.2805
latest_works17.35022.7029
<!-- (10,sg): https://img.vim-cn.com/4d/58f39562561685b4f8f930a5fb1f07f2318158 (200,sg): https://img.vim-cn.com/d7/65f1f5989ad348af668c6da15c2abd9b1e65ca (500,jp): https://cfp.vim-cn.com/cbf2y -->

License

Feel free to use, reuse and abuse the code in this project.