Skip to content

ChenyangGao/p115client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

license PyPI - Python Version PyPI - Version PyPI - Downloads PyPI - Format PyPI - Status

p115client

p115client 是一个 115 网盘Python 客户端模块,不过仅提供最直接的接口包装。

支持同步和异步操作,全面封装了各种 webappopen 接口。

原创玄幻小说《叶不凡修仙记》

安装

你可以从 pypi 安装最新版本

pip install -U p115client

或者从 github 安装最新版本

pip install -U git+https://github.com/ChenyangGao/p115client@main

入门介绍

1. 导入模块

导入模块

from p115client import P115Client

2. 创建实例

1. 用 cookies 创建实例

创建客户端对象,需要传入 cookies,如果不传,则需要扫码登录

cookies = "UID=...; CID=...; SEID=...; KID=..."
client = P115Client(cookies)

如果你的 cookies 保存在 ~/115-cookies.txt

from pathlib import Path

client = P115Client(Path("~/115-cookies.txt").expanduser())

# 或者简便写法
client = P115Client.from_path()

如果想要调用接口返回时自动捕获 405 HTTP 响应码,然后进行自动的扫码登录,并把更新后的 cookies 写回文件,然后重试接口调用

client = P115Client(Path("~/115-cookies.txt").expanduser(), check_for_relogin=True)

所以综上,推荐的初始化代码为

from p115client import P115Client
from pathlib import Path

client = P115Client(Path("~/115-cookies.txt").expanduser(), check_for_relogin=True)

2. 用 AppID 创建实例

如果你有一个申请通过的开放接口的应用,则可以创建开放接口的客户端实例

你可以直接从一个 P115Client 实例拿到授权(自动扫码登录并授权)

app_id = <开放接口应用的 AppID>
# 可以不传 app_id,因为有一个默认值
client_open = client.login_another_open(app_id)

你也可以直接在 P115Client 实例上使用开放接口,此时会使用 P115OpenClient 的对应方法,但名字多一个 "_open" 后缀

# 此时 client.fs_files_open 相当于 client_open.fs_files
client.login_another_open(app_id, replace=True)

也可以用一个已经授权得到的 refresh_token (一次性使用)

from p115client import P115OpenClient

client_open = P115OpenClient(refresh_token)

或者手动扫码登录

client_open = P115OpenClient(app_id)

所以综上,推荐的初始化代码为

from p115client import P115Client, P115OpenClient
from pathlib import Path

client = P115Client(Path("~/115-cookies.txt").expanduser(), check_for_relogin=True)
client_open = client.login_another_open()

3. 接口调用

我推荐你选择 ipython 作为执行环境,可以交互式地执行代码和分析结果

所有需要直接或间接执行 HTTP 请求的接口,都有同步和异步的调用方式

# 同步调用
client.method(payload)
client.method(payload, async_=False)

# 异步调用
await client.method(payload, async_=True)

它们都能接受一个参数 request,具体要求可以查看 P115Client.request 的文档。我也封装了一些模块, 它们都能提供一个符合要求的 request 函数。更一般的实现,可以参考 python-http_request

  1. aiohttp_client_request
  2. aiosonic_request
  3. asks_request
  4. blacksheep_client_request
  5. curl_cffi_request
  6. http_client_request
  7. httpcore_request
  8. httpx_request
  9. hyper_request
  10. pycurl_request
  11. python-urlopen
  12. requests_request
  13. tornado_client_request
  14. urllib3_request

注意:从根本上讲,所有接口的封装,最终都会调用 P115Client.request

url = "https://webapi.115.com/files"
response = client.request(url=url, params={"cid": 0, "show_dir": 1})

当你需要构建自己的扩展模块,以增加一些新的 115 web 接口时,就需要用到此方法了

from collections.abc import Coroutine
from typing import overload, Any, Literal

from p115client import P115Client

class MyCustom115Client(P115Client):

    @overload
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: Literal[False] = False, 
        **request_kwargs, 
    ) -> dict:
        ...
    @overload
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: Literal[True], 
        **request_kwargs, 
    ) -> Coroutine[Any, Any, dict]:
        ...
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: bool = False, 
        **request_kwargs, 
    ) -> dict | Coroutine[Any, Any, dict]:
        api = "https://webapi.115.com/foo"
        return self.request(
            api, 
            method="GET", 
            params=payload, 
            async_=async_, 
            **request_kwargs, 
        )

    @overload
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: Literal[False] = False, 
        **request_kwargs, 
    ) -> dict:
        ...
    @overload
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: Literal[True], 
        **request_kwargs, 
    ) -> Coroutine[Any, Any, dict]:
        ...
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: bool = False, 
        **request_kwargs, 
    ) -> dict | Coroutine[Any, Any, dict]:
        api = "https://webapi.115.com/bar"
        return self.request(
            api, 
            method="POST", 
            data=payload, 
            async_=async_, 
            **request_kwargs, 
        )

4. 检查响应

接口被调用后,如果返回的是 dict 类型的数据(说明原本是 JSON),则可以用 p115client.check_response 执行检查。首先会查看其中名为 "state" 的键的对应值,如果为 True、1 或不存在,则原样返回被检查的数据;否则,"state" 的对应值大概是 False 或 0,说明有问题出现,会根据实际情况抛出一个异常,但都是 p115client.P115OSError 的实例。

from p115client import check_response

# 检查同步调用
data = check_response(client.method(payload))

# 检查异步调用
data = check_response(await client.method(payload, async_=True))
# 或者
data = await check_response(client.method(payload, async_=True))

5. 辅助工具

一些简单的封装工具可能是必要的,特别是那种实现起来代码量比较少,可以封装成单个函数的。我把平常使用过程中,积累的一些经验具体化为一组工具函数。这些工具函数分别有着不同的功能,如果组合起来使用,或许能解决很多问题。

from p115client import tool

6. 实用案例

我写了几篇文章,介绍了 p115client 的一些实践案例。有一些文章打开是空的,说明还未上传。

https://p115client.readthedocs.io/en/latest/example/index.html

其它资源

About

Python 115 client

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published