├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── readme.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.en.md ├── README.md ├── dist ├── tikhub-1.12.7-py3-none-any.whl ├── tikhub-1.12.7.tar.gz ├── tikhub-1.12.8-py3-none-any.whl ├── tikhub-1.12.8.tar.gz ├── tikhub-1.12.9-py3-none-any.whl └── tikhub-1.12.9.tar.gz ├── pyproject.toml ├── requirements.txt ├── setup.py └── tikhub ├── __init__.py ├── api ├── __init__.py └── v1 │ ├── __init__.py │ ├── endpoints │ ├── __init__.py │ ├── bilibili │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── bilibili_web.py │ ├── captcha │ │ ├── __init__.py │ │ └── captcha_solver.py │ ├── douyin │ │ ├── __init__.py │ │ ├── app │ │ │ ├── __init__.py │ │ │ ├── douyin_app_v1.py │ │ │ ├── douyin_app_v2.py │ │ │ └── douyin_app_v3.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── douyin_web.py │ ├── hybrid_parsing │ │ ├── __init__.py │ │ └── hybrid_parsing.py │ ├── instagram │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── instagram_web.py │ ├── kuaishou │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── kuaishou_web.py │ ├── net_ease_cloud_music │ │ ├── __init__.py │ │ └── app │ │ │ ├── __init__.py │ │ │ └── net_ease_cloud_music_app_v1.py │ ├── temp_mail │ │ ├── __init__.py │ │ └── temp_mail_v1.py │ ├── tikhub │ │ ├── __init__.py │ │ └── tikhub_user.py │ ├── tiktok │ │ ├── __init__.py │ │ ├── app │ │ │ ├── __init__.py │ │ │ ├── tiktok_app_v2.py │ │ │ └── tiktok_app_v3.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── tiktok_web.py │ ├── twitter │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── twitter_web.py │ ├── weibo │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── weibo_web.py │ ├── xiaohongshu │ │ ├── __init__.py │ │ └── web │ │ │ ├── __init__.py │ │ │ └── xiaohongshu_web.py │ ├── xigua │ │ ├── __init__.py │ │ └── app │ │ │ ├── __init__.py │ │ │ └── xigua_app_v2.py │ └── youtube │ │ ├── __init__.py │ │ └── web │ │ ├── __init__.py │ │ └── youtube_web.py │ └── models │ ├── APIResponseModel.py │ ├── __init__.py │ └── douyin_web_models.py ├── client ├── __init__.py └── client.py ├── http_client ├── __init__.py ├── api_client.py ├── api_exceptions.py ├── api_logger.py └── deprecated.py ├── test ├── __init__.py └── test.py └── version.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/readme.yml: -------------------------------------------------------------------------------- 1 | name: Translate README 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Setup Node.js 13 | uses: actions/setup-node@v1 14 | with: 15 | node-version: 12.x 16 | # ISO Langusge Codes: https://cloud.google.com/translate/docs/languages 17 | - name: Adding README - English 18 | uses: dephraiim/translate-readme@main 19 | with: 20 | LANG: en -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | wheels/ 22 | pip-wheel-metadata/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | db.sqlite3-journal 62 | 63 | # Flask stuff: 64 | instance/ 65 | .webassets-cache 66 | 67 | # Scrapy stuff: 68 | .scrapy 69 | 70 | # Sphinx documentation 71 | docs/_build/ 72 | 73 | # PyBuilder 74 | target/ 75 | 76 | # Jupyter Notebook 77 | .ipynb_checkpoints 78 | 79 | # IPython 80 | profile_default/ 81 | ipython_config.py 82 | 83 | # pyenv 84 | .python-version 85 | 86 | # pipenv 87 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 88 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 89 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 90 | # install all needed dependencies. 91 | #Pipfile.lock 92 | 93 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 94 | __pypackages__/ 95 | 96 | # Celery stuff 97 | celerybeat-schedule 98 | celerybeat.pid 99 | 100 | # SageMath parsed files 101 | *.sage.py 102 | 103 | # Environments 104 | .env 105 | .venv 106 | env/ 107 | venv/ 108 | ENV/ 109 | env.bak/ 110 | venv.bak/ 111 | 112 | # Spyder project settings 113 | .spyderproject 114 | .spyproject 115 | 116 | # Rope project settings 117 | .ropeproject 118 | 119 | # mkdocs documentation 120 | /site 121 | 122 | # mypy 123 | .mypy_cache/ 124 | .dmypy.json 125 | dmypy.json 126 | 127 | # Pyre type checker 128 | .pyre/ 129 | 130 | # pycharm 131 | .idea/ 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE 3 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 |
2 |

TikHub-API-Python-SDK

3 | English | 简体中文 4 |
5 | 6 | #### **Introduction** 7 | 8 | 🎉「[TikHub.io](https://tikhub.io/)” is a**A platform for out-of-the-box integration tools and services**, our goal is to help users quickly start business and support function customization. Our vision is to form a community entrepreneurship project. A single tree cannot grow into a forest, but cooperation can lead to a win-win situation.**Every community member has the opportunity to integrate the functions or interfaces they write into our platform and benefit from them**. We have accumulated a large number of registered users and community users, and in order to realize this vision, we are actively planning and implementing cooperation strategies to ensure the sustainable and healthy development of the ecosystem. Welcome everyone to join us[Discord](https://discord.gg/aMEAS8Xsvz)Community. 9 | 10 | #### Remark 11 | 12 | - TikHub API currently provides the following services and is constantly being updated: 13 | - [Douyin web version data interface](https://api.tikhub.io/#/Douyin-Web-API) 14 | - [Douyin App V1 data interface](https://api.tikhub.io/#/Douyin-App-V1-API) 15 | - [Douyin App V2 data interface](https://api.tikhub.io/#/Douyin-App-V2-API) 16 | - [Douyin App V3 data interface](https://api.tikhub.io/#/Douyin-App-V3-API) 17 | - [TikTok web version data interface](https://api.tikhub.io/#/TikTok-Web-API) 18 | - [TikTok App V2 data interface](https://api.tikhub.io/#/TikTok-App-V2-API) 19 | - [TikTok App V3 data interface](https://api.tikhub.io/#/TikTok-App-V3-API) 20 | - [Xigua Video App V2 data interface](https://api.tikhub.io/#/Xigua-App-V2-API) 21 | - [Xiaohongshu web version data interface](https://api.tikhub.io/#/Xiaohongshu-Web-API) 22 | - [Kuaishou web version data interface](https://api.tikhub.io/#/Kuaishou-Web-API) 23 | - [Weibo web version data interface](https://api.tikhub.io/#/Weibo-Web-API) 24 | - [Instagram Web and APP data interface](https://api.tikhub.io/#/Instagram-Web-And-APP-API) 25 | - [YouTube web data interface](https://api.tikhub.io/#/YouTube-Web-API) 26 | - [NetEase Cloud Music App Data Interface](https://api.tikhub.io/#/NetEase-Cloud-Music-API) 27 | - [Twitter web data interface](https://api.tikhub.io/#/Twitter-Web-API) 28 | - [Verification code bypass interface](https://api.tikhub.io/#/Captcha-Solver) 29 | - [Temporary mailbox interface](https://api.tikhub.io/#/Temp-Mail-API) 30 | - Please report any issues or bugs to[Discord server](https://discord.gg/aMEAS8Xsvz)。 31 | 32 | * * * 33 | 34 | #### **quick start** 35 | 36 | > References 37 | 38 | - **Swagger UI Docs**:[Swagger UI](https://api.tikhub.io) 39 | - **Documentation/documentation**:[API Documentation](https://docs.tikhub.io/) 40 | 41 | [TikHub.io](https://tikhub.io/)Most of the APIs are RESTFUL, which means you only need to use basic HTTP requests to complete the call. 42 | 43 | All APIs are written based on the OPenAPI specification, which means you can use our`openapi.json`Automatically generate any form of API documentation: 44 | 45 | 46 | 47 | Of course, we have used Swagger UI by default to display our API documents. You can open the following link on the web page, then authenticate the API Token on the web page, then click on any endpoint and click`Try it out`You can test the endpoints you need. Most endpoints already carry default values ​​or demo values, which will better help you understand the required parameters of the call: 48 | 49 | 50 | 51 | * * * 52 | 53 | #### **Authentication** 54 | 55 | > Introduction 56 | 57 | The endpoints with the 🔒 icon in the interface document need to carry the API Token in the request header before they can be called. Calling these interfaces will use the remaining free quota or account balance in your account. At the same time, each endpoint will also be based on the email of the API Token owner. The address limits the request rate. Each endpoint has independent RPS (Requests per second). In most cases, users can request the same endpoint 5 times per second. 58 | 59 | > Generate API Token 60 | 61 | The steps to obtain API Token are also very simple. You only need to log in to our user backend.[Stay tuned](https://beta-web.tikhub.io/users/api_keys), then click on the left`API Keys`You can generate your own API Token, and at the same time, you can customize the permissions of the API Token (`Scopes`), you can also set the expiration date of the API Token (`Expire Date`), you can also manually temporarily close the API Token (`Status`)。 62 | 63 | > Used on the API documentation web page 64 | 65 | After you complete the above steps, you can copy your API Token, then return to our Swagger UI web page and click the green on the right side of the page`Authorize`, and then at the bottom of the pop-up window`Value`Paste the API Token in the input box to complete the authentication. 66 | 67 | > Used in HTTP requests 68 | 69 | If you want to carry the API Token in the HTTP request, please read the format below carefully, and you need to carry a called`Authorization`Field, below I will give an example of JSON as header: 70 | 71 | { 72 | 73 | "Authorization":"Bearer Your_API_Token" 74 | 75 | } 76 | 77 | > Remark 78 | 79 | Please do not share your API Token, as this may cause you to lose property and other problems. We strongly recommend using a different API Token for each of your projects, and don’t forget to check the corresponding box when creating the API Token.`Scopes`, otherwise you will encounter insufficient permissions when requesting. 80 | 81 | * * * 82 | 83 | ## **Use SDK** 84 | 85 | - Install ours via PyPi[SDK](https://pypi.org/project/tikhub/) 86 | 87 | ```console 88 | pip install tikhub 89 | ``` 90 | 91 | - Import SDK 92 | 93 | ```python 94 | from tikhub import Client 95 | ``` 96 | 97 | - InitializeClient 98 | 99 | ```python 100 | client = Client(base_url="https://api.tikhub.io", 101 | api_key="YOUR_API_TOKEN", 102 | proxies=None, 103 | max_retries=3, 104 | max_connections=50, 105 | timeout=60, 106 | max_tasks=50) 107 | ``` 108 | 109 | - Request user data example 110 | 111 | ```python 112 | # 请求用户信息 | Request user info 113 | user_info = await client.TikHubUser.get_user_info() 114 | print(user_info) 115 | 116 | # 请求用户每日使用情况 | Request user daily usage 117 | user_daily_usage = await client.TikHubUser.get_user_daily_usage() 118 | print(user_daily_usage) 119 | 120 | # 计算价格 | Calculate price 121 | price = await client.TikHubUser.calculate_price(endpoint="/api/v1/douyin/app/v1/fetch_one_video", request_per_day=100) 122 | print(price) 123 | 124 | # 获取阶梯式折扣百分比信息 | Get tiered discount percentage information 125 | tiered_discount_info = await client.TikHubUser.get_tiered_discount_info() 126 | print(tiered_discount_info) 127 | 128 | # 获取一个端点的信息 | Get information of an endpoint 129 | endpoint_info = await client.TikHubUser.get_endpoint_info(endpoint="/api/v1/douyin/app/v1/fetch_one_video") 130 | print(endpoint_info) 131 | 132 | # 获取所有端点信息 | Get all endpoints information 133 | all_endpoints_info = await client.TikHubUser.get_all_endpoints_info() 134 | print(all_endpoints_info) 135 | ``` 136 | 137 | - Available properties in Client 138 | 139 | ```python 140 | # TikHub User | TikHub用户接口 141 | self.TikHubUser = TikHubUser(self.client) 142 | 143 | # Douyin | 抖音 144 | self.DouyinWeb = DouyinWeb(self.client) 145 | self.DouyinAppV1 = DouyinAppV1(self.client) 146 | self.DouyinAppV2 = DouyinAppV2(self.client) 147 | self.DouyinAppV3 = DouyinAppV3(self.client) 148 | 149 | # TikTok | TikTok 150 | self.TikTokWeb = TikTokWeb(self.client) 151 | self.TikTokAppV2 = TikTokAppV2(self.client) 152 | self.TikTokAppV3 = TikTokAppV3(self.client) 153 | 154 | # Instagram | Instagram 155 | self.InstagramWeb = InstagramWeb(self.client) 156 | 157 | # Weibo | 微博 158 | self.WeiboWeb = WeiboWeb(self.client) 159 | 160 | # Captcha Solver | 验证码解决器 161 | self.CaptchaSolver = CaptchaSolver(self.client) 162 | 163 | # Xigua Video APP V2 | 西瓜视频APP V2 164 | self.XiguaAppV2 = XiguaAppV2(self.client) 165 | 166 | # XiaoHongShu Web | 小红书网页端 167 | self.XiaohongshuWeb = XiaohongshuWeb(self.client) 168 | 169 | # KuaiShou Web | 快手网页端 170 | self.KuaishouWeb = KuaishouWeb(self.client) 171 | 172 | # YouTube Web | YouTube网页端 173 | self.YouTubeWeb = YouTubeWeb(self.client) 174 | 175 | # 网易云音乐APP | NetEase Cloud Music APP 176 | self.NetEaseCloudMusicAppV1 = NetEaseCloudMusicAppV1(self.client) 177 | 178 | # Twitter Web | Twitter网页端 179 | self.TwitterWeb = TwitterWeb(self.client) 180 | 181 | # Hybrid Parsing 182 | self.HybridParsing = HybridParsing(self.client) 183 | ``` 184 | 185 | - use`DouyinAppV1`of`fetch_one_video`The method calls the interface to obtain single video data. 186 | 187 | ```python 188 | # 导入异步io库 | Import asyncio 189 | import asyncio 190 | 191 | # 导入tikhub | Import tikhub 192 | from tikhub import Client 193 | 194 | # 初始化Client | Initialize Client 195 | client = Client(base_url="https://api.tikhub.io", 196 | api_key="YOUR_API_TOKEN", 197 | proxies=None, 198 | max_retries=3, 199 | max_connections=50, 200 | timeout=60, 201 | max_tasks=50) 202 | 203 | if __name__ == "__main__": 204 | # 获取单个作品数据 | Get single video data 205 | video_data = asyncio.run(client.DouyinAppV1.fetch_one_video(aweme_id="7345492945006595379")) 206 | print(video_data) 207 | ``` 208 | 209 | - We have used HTTPX to asynchronously encapsulate most endpoints. If your code is executed synchronously, you can use the following code to prevent asynchronous infection. 210 | 211 | ```python 212 | # 导入异步io库 | Import asyncio 213 | import asyncio 214 | 215 | # 导入tikhub | Import tikhub 216 | from tikhub import Client 217 | 218 | # 初始化Client | Initialize Client 219 | client = Client(base_url="https://api.tikhub.io", 220 | api_key="YOUR_API_TOKEN", 221 | proxies=None, 222 | max_retries=3, 223 | max_connections=50, 224 | timeout=60, 225 | max_tasks=50) 226 | 227 | # 获取抖音单一视频数据 | Get a single video data from Douyin 228 | def fetch_one_video(aweme_id: str): 229 | # 创建一个异步事件循环 230 | # Create an asynchronous event loop 231 | loop = asyncio.get_event_loop() 232 | 233 | # 使用异步事件循环运行客户端的fetch_one_video方法,防止异步传染到其他代码。 234 | # Run the client's fetch_one_video method with the asynchronous event loop, preventing asynchronous infection to other code. 235 | try: 236 | __video_data = loop.run_until_complete(client.DouyinAppV1.fetch_one_video(aweme_id=aweme_id)) 237 | return __video_data 238 | except Exception as e: 239 | # 如果出现异常,返回异常信息 240 | # If an exception occurs, return the exception information 241 | return str(e) 242 | finally: 243 | # 关闭异步事件循环 244 | # Close the asynchronous event 245 | loop.close() 246 | 247 | # 调用fetch_one_video方法 | Call the fetch_one_video method 248 | if __name__ == "__main__": 249 | video_data = fetch_one_video(aweme_id="7345492945006595379") 250 | print(video_data) 251 | ``` 252 | 253 | - Due to the limited chapters, the complete methods are not listed here. You can view the methods implemented in each attribute by viewing the source code. Each method is named according to the endpoint.`uri`to name, for example`/api/v1/douyin/app/v1/fetch_one_video`The method name is`fetch_one_video`, you can find the corresponding method according to the endpoint in the API document. 254 | - And the parameters accepted by each method have been added`type hints`, you can understand the parameter types that the method needs to pass in by looking at the parameters of the method, which can better help you call the method. 255 | - The document can automatically help you generate codes in different programming languages. Please check for details.[API Documentation](https://docs.tikhub.io/)。 256 | - Currently, the programming languages ​​that can automatically generate code are: 257 | - Shell 258 | - JavaScript 259 | - Java 260 | - Swift 261 | - Go 262 | - PHP 263 | - Python 264 | - HTTP 265 | - C 266 | - C# 267 | - Objective-C 268 | - Ruby 269 | - OCaml 270 | - Dart 271 | - R 272 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

TikHub-API-Python-SDK

3 | English | 简体中文 4 |
5 | 6 | #### **简介** 7 | 8 | 🎉「[TikHub.io](https://tikhub.io/)」是一个**开箱即用的集成工具以及服务的平台**,我们的目标是帮助用户快速开展业务,并且支持功能定制。我们的愿景是组建一个社区创业项目,独木难成林,合作能共赢,**每一个社区成员都有机会将他们编写的功能或接口接入我们的平台,并且从中获得收益**。我们已经积累了大量的注册用户以及社区用户,并且为了实现这一愿景,我们正在积极筹划和落实合作策略,以确保生态的持续健康发展,欢迎各位加入我们的[Discord](https://discord.gg/aMEAS8Xsvz)社区。 9 | 10 | #### 备注 11 | 12 | * TikHub API目前提供以下服务,并且还在不断更新中: 13 | * [抖音网页版数据接口](https://api.tikhub.io/#/Douyin-Web-API) 14 | * [抖音App V1数据接口](https://api.tikhub.io/#/Douyin-App-V1-API) 15 | * [抖音App V2数据接口](https://api.tikhub.io/#/Douyin-App-V2-API) 16 | * [抖音App V3数据接口](https://api.tikhub.io/#/Douyin-App-V3-API) 17 | * [TikTok网页版数据接口](https://api.tikhub.io/#/TikTok-Web-API) 18 | * [TikTok App V2数据接口](https://api.tikhub.io/#/TikTok-App-V2-API) 19 | * [TikTok App V3数据接口](https://api.tikhub.io/#/TikTok-App-V3-API) 20 | * [西瓜视频App V2数据接口](https://api.tikhub.io/#/Xigua-App-V2-API) 21 | * [小红书网页版数据接口](https://api.tikhub.io/#/Xiaohongshu-Web-API) 22 | * [快手网页版数据接口](https://api.tikhub.io/#/Kuaishou-Web-API) 23 | * [微博网页版数据接口](https://api.tikhub.io/#/Weibo-Web-API) 24 | * [Instagram Web以及APP数据接口](https://api.tikhub.io/#/Instagram-Web-And-APP-API) 25 | * [YouTube Web数据接口](https://api.tikhub.io/#/YouTube-Web-API) 26 | * [网易云音乐App数据接口](https://api.tikhub.io/#/NetEase-Cloud-Music-API) 27 | * [Twitter Web数据接口](https://api.tikhub.io/#/Twitter-Web-API) 28 | * [验证码绕过接口](https://api.tikhub.io/#/Captcha-Solver) 29 | * [临时邮箱接口](https://api.tikhub.io/#/Temp-Mail-API) 30 | * 请将任何问题或错误报告给[Discord服务器](https://discord.gg/aMEAS8Xsvz)。 31 | --- 32 | 33 | #### **快速开始** 34 | 35 | > 参考资料 36 | 37 | - **Swagger UI Docs**: [Swagger UI](https://api.tikhub.io) 38 | - **Documentation/文档**: [API Documentation](https://docs.tikhub.io/) 39 | 40 | [TikHub.io](https://tikhub.io/)的大多数API都是RESTFUL的,这意味着你只需要使用基本的HTTP请求即可完成调用。 41 | 42 | 所有的API都是基于OPenAPI规范进行编写的,这意味着你可以使用我们的`openapi.json`自动生成任何形式的API文档: 43 | 44 | [https://api.tikhub.io/openapi.json](https://api.tikhub.io/openapi.json) 45 | 46 | 当然,我们已经默认使用了Swagger UI来展示我们的API文档,你可以在网页上打开下面的链接,然后在网页上进行API Token的认证,随后点击任意端点然后点击`Try it out`即可测试你所需要的端点,大多数端点都已经携带了默认值或演示值,这会更好的帮助你理解调用的所需参数: 47 | 48 | [https://api.tikhub.io](https://api.tikhub.io) 49 | 50 | --- 51 | 52 | #### **鉴权** 53 | 54 | > 简介 55 | 56 | 接口文档中带有🔒图标的端点需要在请求头中携带API Token才可以调用,调用这些接口会使用你账户中的剩余免费额度或账户余额,同时每一个端点还会根据API Token所有者的email地址进行请求速率的限制,每个端点之间都有彼此独立的RPS(Requests per second),在大多数情况下,用户可以每秒请求5次同一个端点。 57 | 58 | > 生成API Token 59 | 60 | 获取API Token的步骤也很简单,你只需要登录到我们的用户后台 [TikHub User](https://beta-web.tikhub.io/users/api_keys),然后点击左侧的`API Keys`就可以生成你自己的API Token,同时,你可以自定义API Token的权限(`Scopes`),也可以设置API Token的过期日期(`Expire Date`),还可以手动暂时关闭API Token(`Status`)。 61 | 62 | > 在API文档网页上使用 63 | 64 | 当你完成上面的步骤后,你可以复制你的API Token,然后回到我们的Swagger UI网页,点击页面右侧的绿色`Authorize`,然后在弹窗底部的`Value`输入框中粘贴API Token即可完成鉴权。 65 | 66 | > 在HTTP请求中使用 67 | 68 | 如果你想在HTTP请求中携带API Token,请仔细阅读下方的格式,并且需要在请求头中携带一个叫`Authorization`的字段,下面我将给出一个JSON作为header的示范: 69 | 70 | { 71 | 72 | "Authorization":"Bearer Your_API_Token" 73 | 74 | } 75 | 76 | > 备注 77 | 78 | 请不要分享你的API Token,这可能会造成你的财产损失等一些列问题,我们强烈建议为你的每一个项目都使用不同的API Token,同时不要忘记在创建API Token时勾选对应的`Scopes`,否则在请求时会遇到权限不足的问题。 79 | 80 | --- 81 | 82 | ## **使用SDK** 83 | 84 | - 通过PyPi安装我们的[SDK](https://pypi.org/project/tikhub/) 85 | 86 | ```console 87 | pip install tikhub 88 | ``` 89 | 90 | - 导入SDK 91 | 92 | ```python 93 | from tikhub import Client 94 | ``` 95 | 96 | - 初始化Client 97 | 98 | ```python 99 | client = Client(base_url="https://api.tikhub.io", 100 | api_key="YOUR_API_TOKEN", 101 | proxies=None, 102 | max_retries=3, 103 | max_connections=50, 104 | timeout=60, 105 | max_tasks=50) 106 | ``` 107 | 108 | - 请求用户数据示例 109 | 110 | ```python 111 | # 请求用户信息 | Request user info 112 | user_info = await client.TikHubUser.get_user_info() 113 | print(user_info) 114 | 115 | # 请求用户每日使用情况 | Request user daily usage 116 | user_daily_usage = await client.TikHubUser.get_user_daily_usage() 117 | print(user_daily_usage) 118 | 119 | # 计算价格 | Calculate price 120 | price = await client.TikHubUser.calculate_price(endpoint="/api/v1/douyin/app/v1/fetch_one_video", request_per_day=100) 121 | print(price) 122 | 123 | # 获取阶梯式折扣百分比信息 | Get tiered discount percentage information 124 | tiered_discount_info = await client.TikHubUser.get_tiered_discount_info() 125 | print(tiered_discount_info) 126 | 127 | # 获取一个端点的信息 | Get information of an endpoint 128 | endpoint_info = await client.TikHubUser.get_endpoint_info(endpoint="/api/v1/douyin/app/v1/fetch_one_video") 129 | print(endpoint_info) 130 | 131 | # 获取所有端点信息 | Get all endpoints information 132 | all_endpoints_info = await client.TikHubUser.get_all_endpoints_info() 133 | print(all_endpoints_info) 134 | ``` 135 | 136 | - Client中的可用属性 137 | 138 | ```python 139 | # TikHub User | TikHub用户接口 140 | self.TikHubUser = TikHubUser(self.client) 141 | 142 | # Douyin | 抖音 143 | self.DouyinWeb = DouyinWeb(self.client) 144 | self.DouyinAppV1 = DouyinAppV1(self.client) 145 | self.DouyinAppV2 = DouyinAppV2(self.client) 146 | self.DouyinAppV3 = DouyinAppV3(self.client) 147 | 148 | # TikTok | TikTok 149 | self.TikTokWeb = TikTokWeb(self.client) 150 | self.TikTokAppV2 = TikTokAppV2(self.client) 151 | self.TikTokAppV3 = TikTokAppV3(self.client) 152 | 153 | # Instagram | Instagram 154 | self.InstagramWeb = InstagramWeb(self.client) 155 | 156 | # Weibo | 微博 157 | self.WeiboWeb = WeiboWeb(self.client) 158 | 159 | # Captcha Solver | 验证码解决器 160 | self.CaptchaSolver = CaptchaSolver(self.client) 161 | 162 | # Xigua Video APP V2 | 西瓜视频APP V2 163 | self.XiguaAppV2 = XiguaAppV2(self.client) 164 | 165 | # XiaoHongShu Web | 小红书网页端 166 | self.XiaohongshuWeb = XiaohongshuWeb(self.client) 167 | 168 | # KuaiShou Web | 快手网页端 169 | self.KuaishouWeb = KuaishouWeb(self.client) 170 | 171 | # YouTube Web | YouTube网页端 172 | self.YouTubeWeb = YouTubeWeb(self.client) 173 | 174 | # 网易云音乐APP | NetEase Cloud Music APP 175 | self.NetEaseCloudMusicAppV1 = NetEaseCloudMusicAppV1(self.client) 176 | 177 | # Twitter Web | Twitter网页端 178 | self.TwitterWeb = TwitterWeb(self.client) 179 | 180 | # Hybrid Parsing 181 | self.HybridParsing = HybridParsing(self.client) 182 | ``` 183 | 184 | - 使用`DouyinAppV1`的`fetch_one_video`方法调用接口获取单一视频数据。 185 | 186 | ```python 187 | # 导入异步io库 | Import asyncio 188 | import asyncio 189 | 190 | # 导入tikhub | Import tikhub 191 | from tikhub import Client 192 | 193 | # 初始化Client | Initialize Client 194 | client = Client(base_url="https://api.tikhub.io", 195 | api_key="YOUR_API_TOKEN", 196 | proxies=None, 197 | max_retries=3, 198 | max_connections=50, 199 | timeout=60, 200 | max_tasks=50) 201 | 202 | if __name__ == "__main__": 203 | # 获取单个作品数据 | Get single video data 204 | video_data = asyncio.run(client.DouyinAppV1.fetch_one_video(aweme_id="7345492945006595379")) 205 | print(video_data) 206 | ``` 207 | 208 | - 我们已经使用HTTPX的对大多数端点进行了异步封装,如果你的代码是同步执行的,你可以使用下面的代码防止异步传染。 209 | 210 | ```python 211 | # 导入异步io库 | Import asyncio 212 | import asyncio 213 | 214 | # 导入tikhub | Import tikhub 215 | from tikhub import Client 216 | 217 | # 初始化Client | Initialize Client 218 | client = Client(base_url="https://api.tikhub.io", 219 | api_key="YOUR_API_TOKEN", 220 | proxies=None, 221 | max_retries=3, 222 | max_connections=50, 223 | timeout=60, 224 | max_tasks=50) 225 | 226 | # 获取抖音单一视频数据 | Get a single video data from Douyin 227 | def fetch_one_video(aweme_id: str): 228 | # 创建一个异步事件循环 229 | # Create an asynchronous event loop 230 | loop = asyncio.get_event_loop() 231 | 232 | # 使用异步事件循环运行客户端的fetch_one_video方法,防止异步传染到其他代码。 233 | # Run the client's fetch_one_video method with the asynchronous event loop, preventing asynchronous infection to other code. 234 | try: 235 | __video_data = loop.run_until_complete(client.DouyinAppV1.fetch_one_video(aweme_id=aweme_id)) 236 | return __video_data 237 | except Exception as e: 238 | # 如果出现异常,返回异常信息 239 | # If an exception occurs, return the exception information 240 | return str(e) 241 | finally: 242 | # 关闭异步事件循环 243 | # Close the asynchronous event 244 | loop.close() 245 | 246 | # 调用fetch_one_video方法 | Call the fetch_one_video method 247 | if __name__ == "__main__": 248 | video_data = fetch_one_video(aweme_id="7345492945006595379") 249 | print(video_data) 250 | ``` 251 | 252 | - 由于章节有限,在此处就不列出完整的方法了,你可以通过查看源代码的形式查看每一个属性内实现的方法,每一个方法的命名都是根据端点的`uri`来命名的,例如`/api/v1/douyin/app/v1/fetch_one_video`的方法名就是`fetch_one_video`,你可以根据API文档中的端点来查找对应的方法。 253 | - 并且每个方法接受的参数都已经加上了`type hints`,你可以通过查看方法的参数来了解该方法需要传入的参数类型,这样可以更好的帮助你调用方法。 254 | - 文档中可以自动帮你生成不同编程语言的代码,具体请查看[API Documentation](https://docs.tikhub.io/)。 255 | - 目前可以自动生成代码的编程语言有: 256 | - Shell 257 | - JavaScript 258 | - Java 259 | - Swift 260 | - Go 261 | - PHP 262 | - Python 263 | - HTTP 264 | - C 265 | - C# 266 | - Objective-C 267 | - Ruby 268 | - OCaml 269 | - Dart 270 | - R 271 | -------------------------------------------------------------------------------- /dist/tikhub-1.12.7-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.7-py3-none-any.whl -------------------------------------------------------------------------------- /dist/tikhub-1.12.7.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.7.tar.gz -------------------------------------------------------------------------------- /dist/tikhub-1.12.8-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.8-py3-none-any.whl -------------------------------------------------------------------------------- /dist/tikhub-1.12.8.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.8.tar.gz -------------------------------------------------------------------------------- /dist/tikhub-1.12.9-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.9-py3-none-any.whl -------------------------------------------------------------------------------- /dist/tikhub-1.12.9.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/dist/tikhub-1.12.9.tar.gz -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | httpx~=0.27.0 2 | rich~=13.7.1 3 | websockets~=12.0 4 | setuptools~=68.2.0 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # RUN Command Line: 4 | # 1.Build-check dist folder 5 | # python setup.py sdist bdist_wheel 6 | # 2.Upload to PyPi 7 | # twine upload dist/* 8 | 9 | from setuptools import setup, find_packages 10 | from tikhub import version 11 | 12 | with open("README.md", "r", encoding='utf8') as fh: 13 | long_description = fh.read() 14 | 15 | setup( 16 | name="tikhub", 17 | version=version, 18 | author="TikHub.io", 19 | author_email="tikhub.io@proton.me", 20 | description="A Python SDK for TikHub RESTful API", 21 | long_description=long_description, 22 | long_description_content_type="text/markdown", 23 | url="https://github.com/TikHubIO/TikHub-API-Python-SDK", 24 | packages=find_packages(), 25 | classifiers=[ 26 | "Programming Language :: Python :: 3", 27 | "License :: OSI Approved :: Apache Software License", 28 | "Operating System :: OS Independent", 29 | ], 30 | python_requires='>=3.6', 31 | install_requires=[ 32 | "httpx>=0.27.0", 33 | "rich~=13.7.1", 34 | "websockets~=12.0", 35 | ], 36 | ) 37 | -------------------------------------------------------------------------------- /tikhub/__init__.py: -------------------------------------------------------------------------------- 1 | from .client.client import Client 2 | from .version import version 3 | 4 | __all__ = ["Client", "version"] 5 | 6 | -------------------------------------------------------------------------------- /tikhub/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/bilibili/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/bilibili/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/bilibili/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/bilibili/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/bilibili/web/bilibili_web.py: -------------------------------------------------------------------------------- 1 | # Import API SDK Client class 2 | from tikhub.http_client.api_client import APIClient 3 | 4 | 5 | class BilibiliWeb: 6 | 7 | # Initialize 8 | def __init__(self, client: APIClient): 9 | self.client = client 10 | 11 | # Fetch single video data | 获取单个视频详情信息 12 | async def fetch_one_video(self, bv_id: str): 13 | endpoint = "/api/v1/bilibili/web/fetch_one_video" 14 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}") 15 | return data 16 | 17 | # Fetch video playurl | 获取视频流地址 18 | async def fetch_video_playurl(self, bv_id: str, cid: str): 19 | endpoint = "/api/v1/bilibili/web/fetch_video_playurl" 20 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}&cid={cid}") 21 | return data 22 | 23 | # Fetch user post videos | 获取用户发布视频作品数据 24 | async def fetch_user_post_videos(self, uid: str, pn: int = 1): 25 | endpoint = "/api/v1/bilibili/web/fetch_user_post_videos" 26 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&pn={pn}") 27 | return data 28 | 29 | # Fetch collection folders | 获取用户所有收藏夹信息 30 | async def fetch_collect_folders(self, uid: str): 31 | endpoint = "/api/v1/bilibili/web/fetch_collect_folders" 32 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}") 33 | return data 34 | 35 | # Fetch videos from collection folder | 获取指定收藏夹内视频数据 36 | async def fetch_user_collection_videos(self, folder_id: str, pn: int = 1): 37 | endpoint = "/api/v1/bilibili/web/fetch_user_collection_videos" 38 | data = await self.client.fetch_get_json(f"{endpoint}?folder_id={folder_id}&pn={pn}") 39 | return data 40 | 41 | # Fetch user profile | 获取指定用户的信息 42 | async def fetch_user_profile(self, uid: str): 43 | endpoint = "/api/v1/bilibili/web/fetch_user_profile" 44 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}") 45 | return data 46 | 47 | # Fetch comprehensive popular videos | 获取综合热门视频信息 48 | async def fetch_com_popular(self, pn: int = 1): 49 | endpoint = "/api/v1/bilibili/web/fetch_com_popular" 50 | data = await self.client.fetch_get_json(f"{endpoint}?pn={pn}") 51 | return data 52 | 53 | # Fetch video comments | 获取指定视频的评论 54 | async def fetch_video_comments(self, bv_id: str, pn: int = 1): 55 | endpoint = "/api/v1/bilibili/web/fetch_video_comments" 56 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}&pn={pn}") 57 | return data 58 | 59 | # Fetch comment reply | 获取视频下指定评论的回复 60 | async def fetch_comment_reply(self, bv_id: str, rpid: str, pn: int = 1): 61 | endpoint = "/api/v1/bilibili/web/fetch_comment_reply" 62 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}&pn={pn}&rpid={rpid}") 63 | return data 64 | 65 | # Fetch user dynamics | 获取指定用户动态 66 | async def fetch_user_dynamic(self, uid: str, offset: str = ""): 67 | endpoint = "/api/v1/bilibili/web/fetch_user_dynamic" 68 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&offset={offset}") 69 | return data 70 | 71 | # Fetch video danmaku | 获取视频实时弹幕 72 | async def fetch_video_danmaku(self, cid: str): 73 | endpoint = "/api/v1/bilibili/web/fetch_video_danmaku" 74 | data = await self.client.fetch_get_json(f"{endpoint}?cid={cid}") 75 | return data 76 | 77 | # Fetch live room details | 获取指定直播间信息 78 | async def fetch_live_room_detail(self, room_id: str): 79 | endpoint = "/api/v1/bilibili/web/fetch_live_room_detail" 80 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 81 | return data 82 | 83 | # Fetch live room videos | 获取指定直播间视频流 84 | async def fetch_live_videos(self, room_id: str): 85 | endpoint = "/api/v1/bilibili/web/fetch_live_videos" 86 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 87 | return data 88 | 89 | # Fetch live streamers in area | 获取指定分区正在直播的主播 90 | async def fetch_live_streamers(self, area_id: str, pn: int = 1): 91 | endpoint = "/api/v1/bilibili/web/fetch_live_streamers" 92 | data = await self.client.fetch_get_json(f"{endpoint}?area_id={area_id}&pn={pn}") 93 | return data 94 | 95 | # Fetch all live areas | 获取所有直播分区列表 96 | async def fetch_all_live_areas(self): 97 | endpoint = "/api/v1/bilibili/web/fetch_all_live_areas" 98 | data = await self.client.fetch_get_json(endpoint) 99 | return data 100 | 101 | # Convert bv_id to aid | 通过bv号获得视频aid号 102 | async def bv_to_aid(self, bv_id: str): 103 | endpoint = "/api/v1/bilibili/web/bv_to_aid" 104 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}") 105 | return data 106 | 107 | # Fetch video parts by bv_id | 通过bv号获得视频分p信息 108 | async def fetch_video_parts(self, bv_id: str): 109 | endpoint = "/api/v1/bilibili/web/fetch_video_parts" 110 | data = await self.client.fetch_get_json(f"{endpoint}?bv_id={bv_id}") 111 | return data 112 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/captcha/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/captcha/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/captcha/captcha_solver.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | 3 | from tikhub.http_client.api_client import APIClient 4 | 5 | 6 | class CaptchaSolver: 7 | # 初始化 | Initialize 8 | def __init__(self, client: APIClient): 9 | self.client = client 10 | 11 | # Cloudflare Turnstile 12 | async def cloudflare_turnstile(self, sitekey: str, url: str, proxy: dict = None): 13 | endpoint = "/api/v1/captcha/cloudflare_turnstile" 14 | payload = { 15 | "sitekey": sitekey, 16 | "url": url, 17 | "proxy": proxy 18 | } 19 | return await self.client.fetch_post_json(endpoint, payload) 20 | 21 | # Recaptcha V2 22 | async def recaptcha_v2(self, sitekey: str, url: str, proxy: dict = None): 23 | endpoint = "/api/v1/captcha/recaptcha_v2" 24 | payload = { 25 | "sitekey": sitekey, 26 | "url": url, 27 | "proxy": proxy 28 | } 29 | return await self.client.fetch_post_json(endpoint, payload) 30 | 31 | # Recaptcha V3 32 | async def recaptcha_v3(self, sitekey: str, url: str, action: str = None, proxy: dict = None): 33 | endpoint = "/api/v1/captcha/recaptcha_v3" 34 | payload = { 35 | "sitekey": sitekey, 36 | "url": url, 37 | "action": action, 38 | "proxy": proxy 39 | } 40 | return await self.client.fetch_post_json(endpoint, payload) 41 | 42 | # hCaptcha 43 | async def hcaptcha(self, sitekey: str, url: str, proxy: dict = None): 44 | endpoint = "/api/v1/captcha/hcaptcha" 45 | payload = { 46 | "sitekey": sitekey, 47 | "url": url, 48 | "proxy": proxy 49 | } 50 | return await self.client.fetch_post_json(endpoint, payload) 51 | 52 | # Tencent Captcha 53 | async def tencent_captcha(self, app_id: str, url: str, proxy: dict = None): 54 | endpoint = "/api/v1/captcha/tencent_captcha" 55 | payload = { 56 | "app_id": app_id, 57 | "url": url, 58 | "proxy": proxy 59 | } 60 | return await self.client.fetch_post_json(endpoint, payload) 61 | 62 | # Amazon Captcha 63 | async def amazon_captcha(self, app_id: str, url: str, proxy: dict = None): 64 | endpoint = "/api/v1/captcha/amazon_captcha" 65 | payload = { 66 | "app_id": app_id, 67 | "url": url, 68 | "proxy": proxy 69 | } 70 | return await self.client.fetch_post_json(endpoint, payload) 71 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/douyin/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/douyin/app/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/app/douyin_app_v1.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | 3 | from tikhub.http_client.api_client import APIClient 4 | 5 | 6 | class DouyinAppV1: 7 | 8 | # 初始化 | Initialize 9 | def __init__(self, client: APIClient): 10 | self.client = client 11 | 12 | # 获取单个作品数据 | Get single video data 13 | async def fetch_one_video(self, aweme_id: str): 14 | endpoint = "/api/v1/douyin/app/v1/fetch_one_video" 15 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}") 16 | return data 17 | 18 | # 根据分享链接获取作品数据 | Get video data by sharing url 19 | async def fetch_one_video_by_share_url(self, share_url: str): 20 | endpoint = "/api/v1/douyin/app/v1/fetch_one_video_by_share_url" 21 | data = await self.client.fetch_get_json(f"{endpoint}?share_url={share_url}") 22 | return data 23 | 24 | # 获取指定用户的信息 | Get information of specified user 25 | async def handler_user_profile(self, sec_user_id: str): 26 | endpoint = f"/api/v1/douyin/app/v1/handler_user_profile" 27 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 28 | return data 29 | 30 | # 获取用户主页作品数据 | Get user homepage video data 31 | async def fetch_user_post_videos(self, sec_user_id: str, max_cursor: int, count: int): 32 | endpoint = f"/api/v1/douyin/app/v1/fetch_user_post_videos" 33 | data = await self.client.fetch_get_json( 34 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&count={count}") 35 | return data 36 | 37 | # 获取用户喜欢作品数据 | Get user like video data 38 | async def fetch_user_like_videos(self, sec_user_id: str, max_cursor: int, counts: int): 39 | endpoint = f"/api/v1/douyin/app/v1/fetch_user_like_videos" 40 | data = await self.client.fetch_get_json( 41 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&counts={counts}") 42 | return data 43 | 44 | # 获取单个视频评论数据 | Get single video comments data 45 | async def fetch_video_comments(self, aweme_id: str, cursor: int, count: int): 46 | endpoint = f"/api/v1/douyin/app/v1/fetch_video_comments" 47 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}") 48 | return data 49 | 50 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 51 | async def fetch_video_comments_reply(self, item_id: str, comment_id: str, cursor: int, count: int): 52 | endpoint = f"/api/v1/douyin/app/v1/fetch_video_comment_replies" 53 | data = await self.client.fetch_get_json( 54 | f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}") 55 | return data 56 | 57 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 58 | async def fetch_general_search_result(self, keyword: str, offset: int, count: int, sort_type: int, 59 | publish_time: int): 60 | endpoint = f"/api/v1/douyin/app/v1/fetch_general_search_result" 61 | data = await self.client.fetch_get_json( 62 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 63 | return data 64 | 65 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 66 | async def fetch_video_search_result(self, keyword: str, offset: int, count: int, sort_type: int, publish_time: int): 67 | endpoint = f"/api/v1/douyin/app/v1/fetch_video_search_result" 68 | data = await self.client.fetch_get_json( 69 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 70 | return data 71 | 72 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 73 | async def fetch_user_search_result(self, keyword: str, offset: int, count: int): 74 | endpoint = f"/api/v1/douyin/app/v1/fetch_user_search_result" 75 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 76 | return data 77 | 78 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 79 | async def fetch_music_search_result(self, keyword: str, offset: int, count: int): 80 | endpoint = f"/api/v1/douyin/app/v1/fetch_music_search_result" 81 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 82 | return data 83 | 84 | # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 85 | async def fetch_hashtag_search_result(self, keyword: str, offset: int, count: int): 86 | endpoint = f"/api/v1/douyin/app/v1/fetch_hashtag_search_result" 87 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 88 | return data 89 | 90 | # 获取指定音乐的详情数据 | Get details of specified music 91 | async def fetch_music_detail(self, music_id: str): 92 | endpoint = f"/api/v1/douyin/app/v1/fetch_music_detail" 93 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 94 | return data 95 | 96 | # 获取指定音乐的视频列表数据 | Get video list of specified music 97 | async def fetch_music_video_list(self, music_id: str, cursor: int, count: int): 98 | endpoint = f"/api/v1/douyin/app/v1/fetch_music_video_list" 99 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&cursor={cursor}&count={count}") 100 | return data 101 | 102 | # 获取指定话题的详情数据 | Get details of specified hashtag 103 | async def fetch_hashtag_detail(self, ch_id: int): 104 | endpoint = f"/api/v1/douyin/app/v1/fetch_hashtag_detail" 105 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}") 106 | return data 107 | 108 | # 获取指定话题的作品数据 | Get video list of specified hashtag 109 | async def fetch_hashtag_post_list(self, ch_id: int, cursor: int, count: int, sort_type: int): 110 | endpoint = f"/api/v1/douyin/app/v1/fetch_hashtag_video_list" 111 | data = await self.client.fetch_get_json( 112 | f"{endpoint}?ch_id={ch_id}&cursor={cursor}&count={count}&sort_type={sort_type}") 113 | return data 114 | 115 | # 获取抖音热搜榜数据 | Get Douyin hot search list data 116 | async def fetch_hot_search_list(self): 117 | endpoint = f"/api/v1/douyin/app/v1/fetch_hot_search_list" 118 | data = await self.client.fetch_get_json(f"{endpoint}") 119 | return data 120 | 121 | # 获取抖音直播热搜榜数据 | Get Douyin live hot search list data 122 | async def fetch_hot_live_search(self): 123 | endpoint = f"/api/v1/douyin/app/v1/fetch_live_hot_search_list" 124 | data = await self.client.fetch_get_json(f"{endpoint}") 125 | return data 126 | 127 | # 获取抖音音乐热榜数据 | Get Douyin music hot search list data 128 | async def fetch_hot_music_search(self): 129 | endpoint = f"/api/v1/douyin/app/v1/fetch_music_hot_search_list" 130 | data = await self.client.fetch_get_json(f"{endpoint}") 131 | return data 132 | 133 | # 获取抖音品牌热榜分类数据 | Get Douyin brand hot search list data 134 | async def fetch_hot_brand_search_category(self): 135 | endpoint = f"/api/v1/douyin/app/v1/fetch_brand_hot_search_list" 136 | data = await self.client.fetch_get_json(f"{endpoint}") 137 | return data 138 | 139 | # 获取抖音品牌热榜具体分类数据 | Get Douyin brand hot search list detail data 140 | async def fetch_hot_brand_search(self, category_id: int): 141 | endpoint = f"/api/v1/douyin/app/v1/fetch_brand_hot_search_list_detail" 142 | data = await self.client.fetch_get_json(f"{endpoint}?category_id={category_id}") 143 | return data 144 | 145 | 146 | if __name__ == "__main__": 147 | import asyncio 148 | 149 | 150 | async def main(): 151 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 152 | "Authorization": "Bearer jZVuQT5gm2gDj3IB0XKPySMV9B4EmLfyqo5okGfltWp7/VAgQt8unAaMEA=="}) 153 | 154 | douyin_app_v1 = DouyinAppV1(client) 155 | 156 | # # 获取单个作品数据 | Get single video data 157 | # data = await douyin_app_v1.fetch_one_video(aweme_id="7345492945006595379") 158 | # print(f"fetch_one_video: {data}") 159 | # 160 | # # 获取指定用户的信息 | Get information of specified user 161 | # data = await douyin_app_v1.handler_user_profile( 162 | # sec_user_id="MS4wLjABAAAAW9FWcqS7RdQAWPd2AA5fL_ilmqsIFUCQ_Iym6Yh9_cUa6ZRqVLjVQSUjlHrfXY1Y") 163 | # print(f"handler_user_profile: {data}") 164 | # 165 | # # 获取用户主页作品数据 | Get user homepage video data 166 | # data = await douyin_app_v1.fetch_user_post_videos( 167 | # sec_user_id="MS4wLjABAAAANXSltcLCzDGmdNFI2Q_QixVTr67NiYzjKOIP5s03CAE", max_cursor=0, count=10) 168 | # print(f"fetch_user_post_videos: {data}") 169 | # 170 | # # 获取用户喜欢作品数据 | Get user like video data 171 | # data = await douyin_app_v1.fetch_user_like_videos( 172 | # sec_user_id="MS4wLjABAAAAW9FWcqS7RdQAWPd2AA5fL_ilmqsIFUCQ_Iym6Yh9_cUa6ZRqVLjVQSUjlHrfXY1Y", max_cursor=0, counts=10) 173 | # print(f"fetch_user_like_videos: {data}") 174 | # 175 | # # 获取单个视频评论数据 | Get single video comments data 176 | # data = await douyin_app_v1.fetch_video_comments(aweme_id="7345492945006595379", cursor=0, count=10) 177 | # print(f"fetch_video_comments: {data}") 178 | # 179 | # # 获取指定视频的评论回复数据 | Get comment replies data of specified video 180 | # data = await douyin_app_v1.fetch_video_comments_reply(item_id="7354666303006723354", 181 | # comment_id="7354669356632638218", 182 | # cursor=0, 183 | # count=10) 184 | # print(f"fetch_video_comments_reply: {data}") 185 | # 186 | # # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 187 | # data = await douyin_app_v1.fetch_general_search_result(keyword="中华娘", offset=0, count=20, sort_type=0, 188 | # publish_time=0) 189 | # print(f"fetch_general_search_result: {data}") 190 | # 191 | # # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 192 | # data = await douyin_app_v1.fetch_video_search_result(keyword="中华娘", offset=0, count=20, sort_type=0, 193 | # publish_time=0) 194 | # print(f"fetch_video_search_result: {data}") 195 | # 196 | # # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 197 | # data = await douyin_app_v1.fetch_user_search_result(keyword="中华娘", offset=0, count=20) 198 | # print(f"fetch_user_search_result: {data}") 199 | # 200 | # # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 201 | # data = await douyin_app_v1.fetch_music_search_result(keyword="中华娘", offset=0, count=20) 202 | # print(f"fetch_music_search_result: {data}") 203 | # 204 | # # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 205 | # data = await douyin_app_v1.fetch_hashtag_search_result(keyword="中华娘", offset=0, count=20) 206 | # print(f"fetch_hashtag_search_result: {data}") 207 | # 208 | # # 获取指定音乐的详情数据 | Get details of specified music 209 | # data = await douyin_app_v1.fetch_music_detail(music_id="7136850194742315016") 210 | # print(f"fetch_music_detail: {data}") 211 | # 212 | # # 抖音音乐视频列表结果 | Get video list of specified music 213 | # data = await douyin_app_v1.fetch_music_video_list(music_id="7136850194742315016", cursor=0, count=10) 214 | # print(f"fetch_music_video_list: {data}") 215 | # 216 | # # 抖音话题详情数据 | Get details of specified hashtag 217 | # data = await douyin_app_v1.fetch_hashtag_detail(ch_id=1575791821492238) 218 | # print(f"fetch_hashtag_detail: {data}") 219 | # 220 | # # 获取指定话题的作品数据 | Get video list of specified hashtag 221 | # data = await douyin_app_v1.fetch_hashtag_post_list(ch_id=1575791821492238, cursor=0, count=10, sort_type=0) 222 | # print(f"fetch_hashtag_post_list: {data}") 223 | # 224 | # # 抖音热搜榜数据 | Get Douyin hot search list data 225 | # data = await douyin_app_v1.fetch_hot_search_list() 226 | # print(f"fetch_hot_search_list: {data}") 227 | # 228 | # # 抖音直播热搜榜数据 | Get Douyin live hot search list data 229 | # data = await douyin_app_v1.fetch_hot_live_search() 230 | # print(f"fetch_hot_live_search: {data}") 231 | # 232 | # # 抖音音乐热榜数据 | Get Douyin music hot search list data 233 | # data = await douyin_app_v1.fetch_hot_music_search() 234 | # print(f"fetch_hot_music_search: {data}") 235 | # 236 | # # 抖音品牌热榜分类数据 | Get Douyin brand hot search list data 237 | # data = await douyin_app_v1.fetch_hot_brand_search_category() 238 | # print(f"fetch_hot_brand_search_category: {data}") 239 | # 240 | # # 抖音品牌热榜具体分类数据 | Get Douyin brand hot search list detail data 241 | # data = await douyin_app_v1.fetch_hot_brand_search(category_id=10) 242 | # print(f"fetch_hot_brand_search: {data}") 243 | 244 | asyncio.run(main()) 245 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/app/douyin_app_v2.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | 3 | from tikhub.http_client.api_client import APIClient 4 | 5 | # 标记已废弃的方法 6 | from tikhub.http_client.deprecated import deprecated 7 | 8 | 9 | class DouyinAppV2: 10 | 11 | # 初始化 | Initialize 12 | def __init__(self, client: APIClient): 13 | self.client = client 14 | 15 | # 获取单个作品数据 | Get single video data 16 | async def fetch_one_video(self, aweme_id: str): 17 | endpoint = f"/api/v1/douyin/app/v2/fetch_one_video" 18 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}") 19 | return data 20 | 21 | # 根据分享链接获取作品数据 | Get video data by sharing url 22 | async def fetch_one_video_by_share_url(self, share_url: str): 23 | endpoint = "/api/v1/douyin/app/v2/fetch_one_video_by_share_url" 24 | data = await self.client.fetch_get_json(f"{endpoint}?share_url={share_url}") 25 | return data 26 | 27 | # 获取指定用户的信息 | Get information of specified user 28 | async def handler_user_profile(self, sec_user_id: str): 29 | endpoint = f"/api/v1/douyin/app/v2/handler_user_profile" 30 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 31 | return data 32 | 33 | # 获取用户主页作品数据 | Get user homepage video data 34 | async def fetch_user_post_videos(self, sec_user_id: str, max_cursor: int, count: int): 35 | endpoint = f"/api/v1/douyin/app/v2/fetch_user_post_videos" 36 | data = await self.client.fetch_get_json( 37 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&count={count}") 38 | return data 39 | 40 | # 获取用户喜欢作品数据 | Get user like video data 41 | async def fetch_user_like_videos(self, sec_user_id: str, max_cursor: int, counts: int): 42 | endpoint = f"/api/v1/douyin/app/v2/fetch_user_like_videos" 43 | data = await self.client.fetch_get_json( 44 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&counts={counts}") 45 | return data 46 | 47 | # 获取单个视频评论数据 | Get single video comments data 48 | async def fetch_video_comments(self, aweme_id: str, cursor: int, count: int): 49 | endpoint = f"/api/v1/douyin/app/v2/fetch_video_comments" 50 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}") 51 | return data 52 | 53 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 54 | async def fetch_video_comments_reply(self, item_id: str, comment_id: str, cursor: int, count: int): 55 | endpoint = f"/api/v1/douyin/app/v2/fetch_video_comment_replies" 56 | data = await self.client.fetch_get_json( 57 | f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}") 58 | return data 59 | 60 | # 获取抖音视频合集详情数据 | Get Douyin video mix detail data 61 | async def fetch_video_mix_detail(self, mix_id: str): 62 | endpoint = f"/api/v1/douyin/app/v2/fetch_video_mix_detail" 63 | data = await self.client.fetch_get_json(f"{endpoint}?mix_id={mix_id}") 64 | return data 65 | 66 | # 获取抖音视频合集作品列表数据 | Get Douyin video mix post list data 67 | async def fetch_video_mix_post_list(self, mix_id: str, cursor: int, count: int): 68 | endpoint = f"/api/v1/douyin/app/v2/fetch_video_mix_post_list" 69 | data = await self.client.fetch_get_json(f"{endpoint}?mix_id={mix_id}&cursor={cursor}&count={count}") 70 | return data 71 | 72 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 73 | @deprecated( 74 | "fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 75 | async def fetch_general_search_result(self, keyword: str, offset: int, count: int, sort_type: int, 76 | publish_time: int): 77 | endpoint = f"/api/v1/douyin/app/v2/fetch_general_search_result" 78 | data = await self.client.fetch_get_json( 79 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 80 | return data 81 | 82 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 83 | @deprecated( 84 | "fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 85 | async def fetch_video_search_result(self, keyword: str, offset: int, count: int, sort_type: int, publish_time: int): 86 | endpoint = f"/api/v1/douyin/app/v2/fetch_video_search_result" 87 | data = await self.client.fetch_get_json( 88 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 89 | return data 90 | 91 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 92 | @deprecated( 93 | "fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 94 | async def fetch_user_search_result(self, keyword: str, offset: int, count: int): 95 | endpoint = f"/api/v1/douyin/app/v2/fetch_user_search_result" 96 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 97 | return data 98 | 99 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 100 | @deprecated( 101 | "fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 102 | async def fetch_music_search_result(self, keyword: str, offset: int, count: int): 103 | endpoint = f"/api/v1/douyin/app/v2/fetch_music_search_result" 104 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 105 | return data 106 | 107 | # 获取指定关键词的话题搜索结果 | Get topic search results of specified keywords 108 | @deprecated( 109 | "fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 110 | async def fetch_hashtag_search_result(self, keyword: str, offset: int, count: int): 111 | endpoint = f"/api/v1/douyin/app/v2/fetch_hashtag_search_result" 112 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 113 | return data 114 | 115 | # 获取指定音乐的详情数据 | Get details of specified music 116 | async def fetch_music_detail(self, music_id: str): 117 | endpoint = f"/api/v1/douyin/app/v2/fetch_music_detail" 118 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 119 | return data 120 | 121 | # 抖音音乐视频列表结果 | Douyin music video list result 122 | async def fetch_music_video_list(self, music_id: str, cursor: int, count: int): 123 | endpoint = f"/api/v1/douyin/app/v2/fetch_music_video_list" 124 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&cursor={cursor}&count={count}") 125 | return data 126 | 127 | # 抖音话题详情数据 | Douyin topic details data 128 | @deprecated("fetch_hashtag_detail is deprecated and will be removed in a future release. Use V3 API instead. | fetch_hashtag_detail已弃用,将在未来版本中删除。请使用V3 API。") 129 | async def fetch_hashtag_detail(self, ch_id: int): 130 | endpoint = f"/api/v1/douyin/app/v2/fetch_hashtag_detail" 131 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}") 132 | return data 133 | 134 | # 获取指定话题的作品数据 | Get video data of specified topic 135 | async def fetch_hashtag_video_list(self, ch_id: int, cursor: int, count: int, sort_type: int): 136 | endpoint = f"/api/v1/douyin/app/v2/fetch_hashtag_video_list" 137 | data = await self.client.fetch_get_json( 138 | f"{endpoint}?ch_id={ch_id}&cursor={cursor}&count={count}&sort_type={sort_type}") 139 | return data 140 | 141 | # 抖音热搜榜数据 | Douyin hot search list data 142 | async def fetch_hot_search_list(self): 143 | endpoint = f"/api/v1/douyin/app/v2/fetch_hot_search_list" 144 | data = await self.client.fetch_get_json(f"{endpoint}") 145 | return data 146 | 147 | # 抖音直播热搜榜数据 | Douyin live hot search list data 148 | async def fetch_live_hot_search_list(self): 149 | endpoint = f"/api/v1/douyin/app/v2/fetch_live_hot_search_list" 150 | data = await self.client.fetch_get_json(f"{endpoint}") 151 | return data 152 | 153 | # 抖音音乐热榜数据 | Douyin music hot search list data 154 | async def fetch_hot_music_search(self): 155 | endpoint = f"/api/v1/douyin/app/v2/fetch_music_hot_search_list" 156 | data = await self.client.fetch_get_json(f"{endpoint}") 157 | return data 158 | 159 | # 抖音品牌热榜分类数据 | Douyin brand hot search category data 160 | async def fetch_hot_brand_search_category(self): 161 | endpoint = f"/api/v1/douyin/app/v2/fetch_brand_hot_search_list" 162 | data = await self.client.fetch_get_json(f"{endpoint}") 163 | return data 164 | 165 | # 抖音品牌热榜具体分类数据 | Douyin brand hot search list detail data 166 | async def fetch_brand_hot_search_list_detail(self, category_id: int): 167 | endpoint = f"/api/v1/douyin/app/v2/fetch_brand_hot_search_list_detail" 168 | data = await self.client.fetch_get_json(f"{endpoint}?category_id={category_id}") 169 | return data 170 | 171 | # 生成抖音短链接 | Generate Douyin short link 172 | async def generate_douyin_short_url(self, url: str): 173 | endpoint = f"/api/v1/douyin/app/v2/generate_douyin_short_url" 174 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 175 | return data 176 | 177 | # 生成抖音视频分享二维码 | Generate Douyin video share QR code 178 | async def generate_douyin_video_share_qrcode(self, object_id: int): 179 | endpoint = f"/api/v1/douyin/app/v2/generate_douyin_video_share_qrcode" 180 | data = await self.client.fetch_get_json(f"{endpoint}?object_id={object_id}") 181 | return data 182 | 183 | 184 | if __name__ == "__main__": 185 | import asyncio 186 | 187 | 188 | async def main(): 189 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 190 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 191 | 192 | douyin_app_v2 = DouyinAppV2(client) 193 | 194 | # # 获取单个作品数据 | Get single video data 195 | # data = await douyin_app_v2.fetch_one_video(aweme_id="7345492945006595379") 196 | # print(f"fetch_one_video: {data}") 197 | # 198 | # # 获取单个视频评论数据 | Get single video comments data 199 | # data = await douyin_app_v2.fetch_video_comments(aweme_id="7345492945006595379", cursor=0, count=10) 200 | # print(f"fetch_video_comments: {data}") 201 | # 202 | # # 获取指定视频的评论回复数据 | Get comment replies data of specified video 203 | # data = await douyin_app_v2.fetch_video_comments_reply(item_id="7354666303006723354", 204 | # comment_id="7354669356632638218", 205 | # cursor=0, 206 | # count=10) 207 | # print(f"fetch_video_comments_reply: {data}") 208 | # 209 | # # 抖音视频合集详情数据 | Douyin video mix detail data 210 | # data = await douyin_app_v2.fetch_video_mix_detail(mix_id="7302011174286002217") 211 | # print(f"fetch_video_mix_detail: {data}") 212 | # 213 | # # 抖音视频合集作品列表数据 | Douyin video mix post list data 214 | # data = await douyin_app_v2.fetch_video_mix_post_list(mix_id="7302011174286002217", cursor=0, count=10) 215 | # print(f"fetch_video_mix_post_list: {data}") 216 | # 217 | # # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 218 | # data = await douyin_app_v2.fetch_general_search_result(keyword="中华娘", offset=0, count=20, sort_type=0, 219 | # publish_time=0) 220 | # print(f"fetch_general_search_result: {data}") 221 | # 222 | # # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 223 | # data = await douyin_app_v2.fetch_video_search_result(keyword="中华娘", offset=0, count=20, sort_type=0, 224 | # publish_time=0) 225 | # print(f"fetch_video_search_result: {data}") 226 | # 227 | # # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 228 | # data = await douyin_app_v2.fetch_user_search_result(keyword="中华娘", offset=0, count=20) 229 | # print(f"fetch_user_search_result: {data}") 230 | # 231 | # # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 232 | # data = await douyin_app_v2.fetch_music_search_result(keyword="中华娘", offset=0, count=20) 233 | # print(f"fetch_music_search_result: {data}") 234 | # 235 | # # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 236 | # data = await douyin_app_v2.fetch_hashtag_search_result(keyword="中华娘", offset=0, count=20) 237 | # print(f"fetch_hashtag_search_result: {data}") 238 | # 239 | # # 获取指定音乐的详情数据 | Get details of specified music 240 | # data = await douyin_app_v2.fetch_music_detail(music_id="7136850194742315016") 241 | # print(f"fetch_music_detail: {data}") 242 | # 243 | # # 抖音音乐视频列表结果 | Get video list of specified music 244 | # data = await douyin_app_v2.fetch_music_video_list(music_id="7136850194742315016", cursor=0, count=10) 245 | # print(f"fetch_music_video_list: {data}") 246 | 247 | # 抖音话题详情数据 | Get details of specified hashtag 248 | # data = await douyin_app_v2.fetch_hashtag_detail(ch_id=1575791821492238) 249 | # print(f"fetch_hashtag_detail: {data}") 250 | 251 | # # 获取指定话题的作品数据 | Get video list of specified hashtag 252 | # data = await douyin_app_v2.fetch_hashtag_video_list(ch_id=1575791821492238, cursor=0, sort_type=0, count=10) 253 | # print(f"fetch_hashtag_video_list: {data}") 254 | # 255 | # # 抖音热搜榜数据 | Get Douyin hot search list data 256 | # data = await douyin_app_v2.fetch_hot_search_list() 257 | # print(f"fetch_hot_search_list: {data}") 258 | # 259 | # # 抖音直播热搜榜数据 | Get Douyin live hot search list data 260 | # data = await douyin_app_v2.fetch_live_hot_search_list() 261 | # print(f"fetch_live_hot_search_list: {data}") 262 | # 263 | # # 抖音音乐热榜数据 | Get Douyin music hot search list data 264 | # data = await douyin_app_v2.fetch_hot_music_search() 265 | # print(f"fetch_hot_music_search: {data}") 266 | # 267 | # # 抖音品牌热榜分类数据 | Get Douyin brand hot search category data 268 | # data = await douyin_app_v2.fetch_hot_brand_search_category() 269 | # print(f"fetch_hot_brand_search_category: {data}") 270 | # 271 | # # 抖音品牌热榜具体分类数据 | Get Douyin brand hot search list detail data 272 | # data = await douyin_app_v2.fetch_brand_hot_search_list_detail(category_id=1) 273 | # print(f"fetch_brand_hot_search_list_detail: {data}") 274 | # 275 | # # 生成抖音短链接 | Generate Douyin short link 276 | # data = await douyin_app_v2.generate_douyin_short_url(url="https://v.douyin.com/e3m8a8t/") 277 | # print(f"generate_douyin_short_url: {data}") 278 | 279 | # 生成抖音视频分享二维码 | Generate Douyin video share QR code 280 | # data = await douyin_app_v2.generate_douyin_video_share_qrcode(object_id=7348044435755846962) 281 | # print(f"generate_douyin_video_share_qrcode: {data}") 282 | 283 | 284 | asyncio.run(main()) 285 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/app/douyin_app_v3.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | from typing import List 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | # 标记已废弃的方法 7 | from tikhub.http_client.deprecated import deprecated 8 | 9 | 10 | class DouyinAppV3: 11 | 12 | # 初始化 | Initialize 13 | def __init__(self, client: APIClient): 14 | self.client = client 15 | 16 | # 获取单个作品数据 17 | async def fetch_one_video(self, aweme_id: str): 18 | endpoint = f"/api/v1/douyin/app/v3/fetch_one_video" 19 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}") 20 | return data 21 | 22 | # 批量获取视频信息 (Batch Get Video Information) 23 | async def fetch_multi_video(self, aweme_ids: List[str]): 24 | endpoint = f"/api/v1/douyin/app/v3/fetch_multi_video" 25 | data = await self.client.fetch_post_json(endpoint, params={"aweme_ids": aweme_ids}) 26 | return data 27 | 28 | # 根据分享链接获取作品数据 | Get video data by sharing url 29 | async def fetch_one_video_by_share_url(self, share_url: str): 30 | endpoint = "/api/v1/douyin/app/v3/fetch_one_video_by_share_url" 31 | data = await self.client.fetch_get_json(f"{endpoint}?share_url={share_url}") 32 | return data 33 | 34 | # 根据视频ID获取作品的统计数据 | Get the statistical data of the work according to the video ID 35 | async def fetch_video_statistics(self, aweme_ids: str): 36 | endpoint = "/api/v1/douyin/app/v3/fetch_video_statistics" 37 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_ids={aweme_ids}") 38 | return data 39 | 40 | # 获取指定用户的信息 41 | async def handler_user_profile(self, sec_user_id: str): 42 | endpoint = f"/api/v1/douyin/app/v3/handler_user_profile" 43 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 44 | return data 45 | 46 | # 获取用户作品集合数据 47 | async def fetch_user_post_videos(self, sec_user_id: str, max_cursor: int, count: int): 48 | endpoint = f"/api/v1/douyin/app/v3/fetch_user_post_videos" 49 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&count={count}") 50 | return data 51 | 52 | # 获取用户喜欢作品数据 53 | async def fetch_user_like_videos(self, sec_user_id: str, max_cursor: int, counts: int): 54 | endpoint = f"/api/v1/douyin/app/v3/fetch_user_like_videos" 55 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&counts={counts}") 56 | return data 57 | 58 | # 获取单个视频评论数据 59 | async def fetch_video_comments(self, aweme_id: str, cursor: int, count: int): 60 | endpoint = f"/api/v1/douyin/app/v3/fetch_video_comments" 61 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}") 62 | return data 63 | 64 | # 获取指定视频的评论回复数据 65 | async def fetch_video_comments_reply(self, item_id: str, comment_id: str, cursor: int, count: int): 66 | endpoint = f"/api/v1/douyin/app/v3/fetch_video_comment_replies" 67 | data = await self.client.fetch_get_json(f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}") 68 | return data 69 | 70 | # 抖音视频合集详情数据 71 | async def fetch_video_mix_detail(self, mix_id: str): 72 | endpoint = f"/api/v1/douyin/app/v3/fetch_video_mix_detail" 73 | data = await self.client.fetch_get_json(f"{endpoint}?mix_id={mix_id}") 74 | return data 75 | 76 | # 抖音视频合集作品列表数据 77 | async def fetch_video_mix_post_list(self, mix_id: str, cursor: int, count: int): 78 | endpoint = f"/api/v1/douyin/app/v3/fetch_video_mix_post_list" 79 | data = await self.client.fetch_get_json(f"{endpoint}?mix_id={mix_id}&cursor={cursor}&count={count}") 80 | return data 81 | 82 | # 获取指定关键词的综合搜索结果 83 | async def fetch_general_search_result(self, keyword: str, offset: int, count: int, sort_type: str, publish_time: str, filter_duration: str, content_type: str): 84 | endpoint = f"/api/v1/douyin/app/v3/fetch_general_search_result" 85 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}&filter_duration={filter_duration}&content_type={content_type}") 86 | return data 87 | 88 | # 获取指定关键词的视频搜索结果 89 | async def fetch_video_search_result(self, keyword: str, offset: int, count: int, sort_type: str, publish_time: str, filter_duration: str): 90 | endpoint = f"/api/v1/douyin/app/v3/fetch_video_search_result" 91 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}&filter_duration={filter_duration}") 92 | return data 93 | 94 | # 获取指定关键词的用户搜索结果 95 | async def fetch_user_search_result(self, keyword: str, offset: int, count: int, douyin_user_fans: str, douyin_user_type: str): 96 | endpoint = f"/api/v1/douyin/app/v3/fetch_user_search_result" 97 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&douyin_user_fans={douyin_user_fans}&douyin_user_type={douyin_user_type}") 98 | return data 99 | 100 | # 获取指定关键词的直播搜索结果 101 | async def fetch_live_search_result(self, keyword: str, cursor: int, count: int): 102 | endpoint = f"/api/v1/douyin/app/v3/fetch_live_search_result" 103 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&cursor={cursor}&count={count}") 104 | return data 105 | 106 | # 获取指定关键词的音乐搜索结果 107 | async def fetch_music_search_result(self, keyword: str, offset: int, count: int): 108 | endpoint = f"/api/v1/douyin/app/v3/fetch_music_search_result" 109 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 110 | return data 111 | 112 | # 获取指定关键词的话题搜索结果 113 | async def fetch_hashtag_search_result(self, keyword: str, offset: int, count: int): 114 | endpoint = f"/api/v1/douyin/app/v3/fetch_hashtag_search_result" 115 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 116 | return data 117 | 118 | # 获取指定音乐的详情数据 119 | async def fetch_music_detail(self, music_id: str): 120 | endpoint = f"/api/v1/douyin/app/v3/fetch_music_detail" 121 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 122 | return data 123 | 124 | # 抖音音乐视频列表结果 125 | async def fetch_music_video_list(self, music_id: str, cursor: int, count: int): 126 | endpoint = f"/api/v1/douyin/app/v3/fetch_music_video_list" 127 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&cursor={cursor}&count={count}") 128 | return data 129 | 130 | # 抖音话题详情数据 131 | async def fetch_hashtag_detail(self, ch_id: int): 132 | endpoint = f"/api/v1/douyin/app/v3/fetch_hashtag_detail" 133 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}") 134 | return data 135 | 136 | # 获取指定话题的作品数据 137 | async def fetch_hashtag_video_list(self, ch_id: int, cursor: int, sort_type: int, count: int): 138 | endpoint = f"/api/v1/douyin/app/v3/fetch_hashtag_video_list" 139 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}&cursor={cursor}&sort_type={sort_type}&count={count}") 140 | return data 141 | 142 | # 抖音热搜榜数据 143 | async def fetch_hot_search_list(self): 144 | endpoint = f"/api/v1/douyin/app/v3/fetch_hot_search_list" 145 | data = await self.client.fetch_get_json(f"{endpoint}") 146 | return data 147 | 148 | # 抖音直播热搜榜数据 149 | async def fetch_hot_live_search(self): 150 | endpoint = f"/api/v1/douyin/app/v3/fetch_live_hot_search_list" 151 | data = await self.client.fetch_get_json(f"{endpoint}") 152 | return data 153 | 154 | # 抖音音乐热榜数据 155 | async def fetch_hot_music_search(self): 156 | endpoint = f"/api/v1/douyin/app/v3/fetch_music_hot_search_list" 157 | data = await self.client.fetch_get_json(f"{endpoint}") 158 | return data 159 | 160 | # 抖音品牌热榜分类数据 161 | async def fetch_hot_brand_search_category(self): 162 | endpoint = f"/api/v1/douyin/app/v3/fetch_brand_hot_search_list" 163 | data = await self.client.fetch_get_json(f"{endpoint}") 164 | return data 165 | 166 | # 抖音品牌热榜具体分类数据 167 | async def fetch_hot_brand_search(self, category_id: int): 168 | endpoint = f"/api/v1/douyin/app/v3/fetch_brand_hot_search_list_detail" 169 | data = await self.client.fetch_get_json(f"{endpoint}?category_id={category_id}") 170 | return data 171 | 172 | # 生成抖音短链接 173 | async def fetch_douyin_short_url(self, url: str): 174 | endpoint = f"/api/v1/douyin/app/v3/generate_douyin_short_url" 175 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 176 | return data 177 | 178 | # 生成抖音视频分享二维码 179 | async def fetch_douyin_video_qrcode(self, object_id: str): 180 | endpoint = f"/api/v1/douyin/app/v3/generate_douyin_video_share_qrcode" 181 | data = await self.client.fetch_get_json(f"{endpoint}?object_id={object_id}") 182 | return data 183 | 184 | # 用户粉丝列表 (User Fans List) 185 | async def fetch_user_fans_list(self, sec_user_id: str, max_time: str = '0', count: int = 20): 186 | endpoint = f"/api/v1/douyin/app/v3/fetch_user_fans_list" 187 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}&max_time={max_time}&count={count}") 188 | return data 189 | 190 | # 用户关注列表 (User Following List) 191 | async def fetch_user_following_list(self, sec_user_id: str, max_time: str = '0', count: int = 20): 192 | endpoint = f"/api/v1/douyin/app/v3/fetch_user_following_list" 193 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}&max_time={max_time}&count={count}") 194 | return data 195 | 196 | # 抖音APP注册设备 (Douyin App Register Device) 197 | async def register_device(self, proxy: str = ''): 198 | endpoint = f"/api/v1/douyin/app/v3/register_device" 199 | data = await self.client.fetch_post_json(f"{endpoint}?proxy={proxy}") 200 | return data 201 | 202 | 203 | if __name__ == "__main__": 204 | import asyncio 205 | 206 | 207 | async def main(): 208 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 209 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 210 | 211 | douyin_app_v3 = DouyinAppV3(client) 212 | 213 | # 获取单个作品数据 214 | data = await douyin_app_v3.fetch_one_video("6954433834136592141") 215 | print(data) 216 | 217 | # 获取指定用户的信息 218 | data = await douyin_app_v3.handler_user_profile("MS4wLjABAAAA9VQ5z5zq8s7tjUvJ1nJYwzYz1pQ5Zb1z9z4Q1z4z1o") 219 | print(data) 220 | 221 | # 获取用户作品集合数据 222 | data = await douyin_app_v3.fetch_user_post_videos("MS4wLjABAAAA9VQ5z5zq8s7tjUvJ1nJYwzYz1pQ5Zb1z9z4Q1z4z1o", 0, 10) 223 | print(data) 224 | 225 | # 获取用户喜欢作品数据 226 | data = await douyin_app_v3.fetch_user_like_videos("MS4wLjABAAAA9VQ5z5zq8s7tjUvJ1nJYwzYz1pQ5Zb1z9z4Q1z4z1o", 0, 10) 227 | print(data) 228 | 229 | # 获取单个视频评论数据 230 | data = await douyin_app_v3.fetch_video_comments("6954433834136592141", 0, 10) 231 | print(data) 232 | 233 | # 获取指定视频的评论回复数据 234 | data = await douyin_app_v3.fetch_video_comments_reply("6954433834136592141", "6954433834136592141", 0, 10) 235 | print(data) 236 | 237 | # 抖音视频合集详情数据 238 | data = await douyin_app_v3.fetch_video_mix_detail("6954433834136592141") 239 | print(data) 240 | 241 | # 抖音视频合集作品列表数据 242 | data = await douyin_app_v3.fetch_video_mix_post_list("6954433834136592141", 0, 10) 243 | print(data) 244 | 245 | # 获取指定关键词的综合搜索结果 246 | data = await douyin_app_v3.fetch_general_search_result("抖音", 0, 10, "general", "all", "all", "all") 247 | print(data) 248 | 249 | # 获取指定关键词的视频搜索结果 250 | data = await douyin_app_v3.fetch_video_search_result("抖音", 0, 10, "general", "all", "all") 251 | print(data) 252 | 253 | # 获取指定关键词的用户搜索结果 254 | data = await douyin_app_v3.fetch_user_search_result("抖音", 0, 10, "all", "all") 255 | print(data) 256 | 257 | # 获取指定关键词的直播搜索结果 258 | data = await douyin_app_v3.fetch_live_search_result("抖音", 0, 10) 259 | print(data) 260 | 261 | # 获取指定关键词的音乐搜索结果 262 | data = await douyin_app_v3.fetch_music_search_result("抖音", 0, 10) 263 | print(data) 264 | 265 | # 获取指定关键词的话题搜索结果 266 | data = await douyin_app_v3.fetch_hashtag_search_result("抖音", 0, 10) 267 | print(data) 268 | 269 | # 获取指定音乐的详情数据 270 | data = await douyin_app_v3.fetch_music_detail("6954433834136592141") 271 | print(data) 272 | 273 | # 抖音音乐视频列表结果 274 | data = await douyin_app_v3.fetch_music_video_list("6954433834136592141", 0, 10) 275 | print(data) 276 | 277 | # 抖音话题详情数据 278 | data = await douyin_app_v3.fetch_hashtag_detail(6954433834136592141) 279 | print(data) 280 | 281 | # 获取指定话题的作品数据 282 | data = await douyin_app_v3.fetch_hashtag_video_list(6954433834136592141, 0, 0, 10) 283 | print(data) 284 | 285 | # 抖音热搜榜数据 286 | data = await douyin_app_v3.fetch_hot_search_list() 287 | print(data) 288 | 289 | # 抖音直播热搜榜数据 290 | data = await douyin_app_v3.fetch_hot_live_search() 291 | print(data) 292 | 293 | # 抖音音乐热榜数据 294 | data = await douyin_app_v3.fetch_hot_music_search() 295 | print(data) 296 | 297 | # 抖音品牌热榜分类数据 298 | data = await douyin_app_v3.fetch_hot_brand_search_category() 299 | print(data) 300 | 301 | # 抖音品牌热榜具体分类数据 302 | data = await douyin_app_v3.fetch_hot_brand_search(1) 303 | print(data) 304 | 305 | # 生成抖音短链接 306 | data = await douyin_app_v3.fetch_douyin_short_url("https://v.douyin.com/e8e3m5v/") 307 | print(data) 308 | 309 | # 生成抖音视频分享二维码 310 | data = await douyin_app_v3.fetch_douyin_video_qrcode("6954433834136592141") 311 | print(data) 312 | 313 | 314 | asyncio.run(main()) -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/douyin/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/douyin/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/hybrid_parsing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/hybrid_parsing/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/hybrid_parsing/hybrid_parsing.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class HybridParsing: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 抖音TikTok的混合解析 | Hybrid parsing of Douyin and TikTok 14 | async def video_data(self, url: str, minimal: bool = False, base64_url: bool = False): 15 | endpoint = "/api/v1/hybrid/video_data" 16 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}&minimal={minimal}&base64_url={base64_url}") 17 | return data 18 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/instagram/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/instagram/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/instagram/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/instagram/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/instagram/web/instagram_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class InstagramWeb: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 根据用户名获取用户数据 | Get user data by username 14 | async def fetch_user_info_by_username(self, username: str): 15 | endpoint = "/api/v1/instagram/web_app/fetch_user_info_by_username" 16 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}") 17 | return data 18 | 19 | # 根据用户ID获取用户数据 | Get user data by user ID 20 | async def fetch_user_info_by_user_id(self, user_id: str): 21 | endpoint = "/api/v1/instagram/web_app/fetch_user_info_by_user_id" 22 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 23 | return data 24 | 25 | # 根据用户名获取用户数据V2 | Get user data by username V2 26 | async def fetch_user_info_by_user_id_v2(self, username: str): 27 | endpoint = "/api/v1/instagram/web_app/fetch_user_info_by_user_id_v2" 28 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={username}") 29 | return data 30 | 31 | # 根据用户ID获取用户数据V2 | Get user data by user ID V2 32 | async def fetch_user_info_by_id_v2(self, user_id: str): 33 | endpoint = "/api/v1/instagram/web_app/fetch_user_info_by_user_id_v2" 34 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 35 | return data 36 | 37 | # 根据用户ID获取用户数据关于信息 | Get user data about by user ID 38 | async def fetch_user_about_info_by_user_id(self, user_id: str): 39 | endpoint = "/api/v1/instagram/web_app/fetch_user_about_info_by_user_id" 40 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 41 | return data 42 | 43 | # 根据用户名获取用户网页接口的个人信息 | Get user info by username web API 44 | async def fetch_user_info_by_username_web(self, username: str): 45 | endpoint = "/api/v1/instagram/web_app/fetch_user_info_by_username_web" 46 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}") 47 | return data 48 | 49 | # 根据用户名获取用户的粉丝数据 | Get user followers by username 50 | async def fetch_user_followers_by_username(self, username: str, pagination_token: str = None): 51 | endpoint = "/api/v1/instagram/web_app/fetch_user_followers_by_username" 52 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}&pagination_token={pagination_token}") 53 | return data 54 | 55 | # 根据用户名获取用户的正在关注的用户数据 | Get user followings by username 56 | async def fetch_user_following_by_username(self, username: str, pagination_token: str = None): 57 | endpoint = "/api/v1/instagram/web_app/fetch_user_following_by_username" 58 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}&pagination_token={pagination_token}") 59 | return data 60 | 61 | # 根据用户ID获取用户发布的帖子 | Get user posts by user ID 62 | async def fetch_user_posts_by_user_id(self, user_id: str, count: int = 12, end_cursor: str = None): 63 | endpoint = "/api/v1/instagram/web_app/fetch_user_posts_by_user_id" 64 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&count={count}&end_cursor={end_cursor}") 65 | return data 66 | 67 | # 根据用户ID获取用户发布的快拍 | Get user reels by user ID 68 | async def fetch_user_reels_by_user_id(self, user_id: str, count: int = 12, max_id: str = None): 69 | endpoint = "/api/v1/instagram/web_app/fetch_user_reels_by_user_id" 70 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&count={count}&max_id={max_id}") 71 | return data 72 | 73 | # 根据用户ID获取用户被标记的帖子 | Get user tagged posts by user ID 74 | async def fetch_user_tagged_posts_by_user_id(self, user_id: str, count: int = 12, end_cursor: str = None): 75 | endpoint = "/api/v1/instagram/web_app/fetch_user_tagged_posts_by_user_id" 76 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&count={count}&end_cursor={end_cursor}") 77 | return data 78 | 79 | # 根据用户ID获取与用户相关的其他用户 | Get user related users by user ID 80 | async def fetch_related_users_by_user_id(self, user_id: str): 81 | endpoint = "/api/v1/instagram/web_app/fetch_related_users_by_user_id" 82 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 83 | return data 84 | 85 | # 根据用户名获取相似的账户数据 | Get similar accounts by username 86 | async def fetch_similar_accounts_by_username(self, username: str): 87 | endpoint = "/api/v1/instagram/web_app/fetch_similar_accounts_by_username" 88 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}") 89 | return data 90 | 91 | # 根据关键词搜索用户 | Search users by query 92 | async def fetch_search_users_by_keyword(self, keyword: str): 93 | endpoint = "/api/v1/instagram/web_app/fetch_search_users_by_keyword" 94 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}") 95 | return data 96 | 97 | # 根据URL获取帖子数据 | Get post data by URL 98 | async def fetch_post_info_by_url(self, url: str): 99 | endpoint = "/api/v1/instagram/web_app/fetch_post_info_by_url" 100 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 101 | return data 102 | 103 | # 根据帖子ID获取帖子数据 | Get post data by post ID 104 | async def fetch_post_info_by_post_id(self, post_id: str): 105 | endpoint = "/api/v1/instagram/web_app/fetch_post_info_by_post_id" 106 | data = await self.client.fetch_get_json(f"{endpoint}?post_id={post_id}") 107 | return data 108 | 109 | # 根据帖子URL获取媒体数据 | Get media data by URL 110 | async def fetch_post_media_by_url(self, url: str): 111 | endpoint = "/api/v1/instagram/web_app/fetch_post_media_by_url" 112 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 113 | return data 114 | 115 | # 根据音乐ID获取音乐数据 | Get music data by music ID 116 | async def fetch_music_info_by_music_id(self, music_id: str): 117 | endpoint = "/api/v1/instagram/web_app/fetch_music_info_by_music_id" 118 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 119 | return data 120 | 121 | # 根据关键词搜索话题数据 | Search hashtags by query 122 | async def fetch_search_hashtags_by_keyword(self, keyword: str): 123 | endpoint = "/api/v1/instagram/web_app/fetch_search_hashtags_by_keyword" 124 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}") 125 | return data 126 | 127 | # 根据关键词获取话题帖子 | Get hashtag posts by query 128 | async def fetch_hashtag_posts_by_keyword(self, keyword: str, end_cursor: str = None): 129 | endpoint = "/api/v1/instagram/web_app/fetch_hashtag_posts_by_keyword" 130 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&end_cursor={end_cursor}") 131 | return data 132 | 133 | # 根据关键词搜索地点数据 | Search locations by query 134 | async def fetch_search_locations_by_keyword(self, keyword: str): 135 | endpoint = "/api/v1/instagram/web_app/fetch_search_locations_by_keyword" 136 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}") 137 | return data 138 | 139 | # 根据地点ID获取地点相关的帖子 | Get location posts by location ID 140 | async def fetch_location_posts_by_location_id(self, location_id: str, max_id: str = None): 141 | endpoint = "/api/v1/instagram/web_app/fetch_location_posts_by_location_id" 142 | data = await self.client.fetch_get_json(f"{endpoint}?location_id={location_id}&max_id={max_id}") 143 | return data 144 | 145 | # 综合搜索 | Search all by query 146 | async def fetch_global_search(self, keyword: str): 147 | endpoint = "/api/v1/instagram/web_app/fetch_global_search" 148 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}") 149 | return data 150 | 151 | # 根据用户名获取用户的Reels数据V2 | Get user reels by username V2 152 | async def fetch_user_reels_by_username_v2(self, username: str, pagination_token: str = None): 153 | endpoint = "/api/v1/instagram/web_app/fetch_user_reels_by_username_v2" 154 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}&pagination_token={pagination_token}") 155 | return data 156 | 157 | # 根据用户名获取用户的Stories数据 | Get user stories by username 158 | async def fetch_user_stories_by_username(self, username: str): 159 | endpoint = "/api/v1/instagram/web_app/fetch_user_stories_by_username" 160 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}") 161 | return data 162 | 163 | # 根据用户名获取用户的highlights数据 | Get user highlights by username 164 | async def fetch_user_highlights_by_username(self, username: str): 165 | endpoint = "/api/v1/instagram/web_app/fetch_user_highlights_by_username" 166 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}") 167 | return data 168 | 169 | # 根据highlights ID获取highlights数据 | Get highlights data by highlights ID 170 | async def fetch_highlights_by_highlights_id(self, highlight_id: str): 171 | endpoint = "/api/v1/instagram/web_app/fetch_highlights_by_highlight_id" 172 | data = await self.client.fetch_get_json(f"{endpoint}?highlight_id={highlight_id}") 173 | return data 174 | 175 | # 根据用户名获取用户的tv_posts数据 | Get user tv_posts by username 176 | async def fetch_user_tv_posts_by_username(self, username: str, pagination_token: str = None): 177 | endpoint = "/api/v1/instagram/web_app/fetch_user_tv_posts_by_username" 178 | data = await self.client.fetch_get_json(f"{endpoint}?username={username}&pagination_token={pagination_token}") 179 | return data 180 | 181 | # 根据URL获取帖子评论数据 | Get post comments by URL 182 | async def fetch_post_comments_by_url(self, url: str, pagination_token: str = None): 183 | endpoint = "/api/v1/instagram/web_app/fetch_post_comments_by_url" 184 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}&pagination_token={pagination_token}") 185 | return data 186 | 187 | # 根据评论ID获取评论回复数据 | Get comment replies by comment ID 188 | async def fetch_comment_replies_by_comment_id(self, url: str, comment_id: str, pagination_token: str = None): 189 | endpoint = "/api/v1/instagram/web_app/fetch_comment_replies_by_comment_id" 190 | data = await self.client.fetch_get_json( 191 | f"{endpoint}?url={url}&comment_id={comment_id}&pagination_token={pagination_token}") 192 | return data 193 | 194 | # 根据URL获取帖子点赞数据 | Get post likes by URL 195 | async def fetch_post_likes_by_url(self, url: str): 196 | endpoint = "/api/v1/instagram/web_app/fetch_post_likes_by_url" 197 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 198 | return data 199 | 200 | 201 | if __name__ == "__main__": 202 | import asyncio 203 | 204 | 205 | async def main(): 206 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 207 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 208 | 209 | instagram_web = InstagramWeb(client) 210 | 211 | # 获取用户信息 | Fetch user info 212 | data = await instagram_web.fetch_user_info_by_username("instagram") 213 | print(data) 214 | 215 | 216 | asyncio.run(main()) 217 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/kuaishou/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/kuaishou/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/kuaishou/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/kuaishou/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/kuaishou/web/kuaishou_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class KuaishouWeb: 8 | 9 | def __init__(self, client: APIClient): 10 | self.client = client 11 | 12 | # 获取单个作品数据 (Fetch Single Video) 13 | async def fetch_one_video(self, photo_id: str): 14 | endpoint = "/api/v1/kuaishou/web/fetch_one_video" 15 | data = await self.client.fetch_get_json(f"{endpoint}?photo_id={photo_id}") 16 | return data 17 | 18 | # 快手单一视频查询接口V2 (Kuaishou Single Video Query API V2) 19 | async def fetch_one_video_v2(self, photo_id: str, isLongVideo: bool = False): 20 | endpoint = "/api/v1/kuaishou/web/fetch_one_video_v2" 21 | data = await self.client.fetch_get_json(f"{endpoint}?photo_id={photo_id}&isLongVideo={isLongVideo}") 22 | return data 23 | 24 | # 根据链接获取单个作品数据 (Fetch Single Video By URL) 25 | async def fetch_one_video_by_url(self, url: str): 26 | endpoint = "/api/v1/kuaishou/web/fetch_one_video_by_url" 27 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 28 | return data 29 | 30 | # 根据链接获取单个作品数据V2 (Fetch Single Video By URL V2) 31 | async def fetch_one_video_by_url_v2(self, url: str): 32 | endpoint = "/api/v1/kuaishou/web/fetch_one_video_by_url_v2" 33 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 34 | return data 35 | 36 | # 获取单个作品评论数据 (Fetch Single Video Comment Data) 37 | async def fetch_one_video_comment(self, photo_id: str, pcursor: str = None): 38 | endpoint = "/api/v1/kuaishou/web/fetch_one_video_comment" 39 | data = await self.client.fetch_get_json(f"{endpoint}?photo_id={photo_id}&pcursor={pcursor}") 40 | return data 41 | 42 | # 获取主页视频数据 (Fetch Home Page Video Data) 43 | async def fetch_home_page_video(self, user_id: str, pcursor: str = None): 44 | endpoint = "/api/v1/kuaishou/web/fetch_home_page_video" 45 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&pcursor={pcursor}") 46 | return data 47 | 48 | # 获取主页信息数据 (Fetch Home Page Info Data) 49 | async def fetch_home_page_info(self, user_id: str): 50 | endpoint = "/api/v1/kuaishou/web/fetch_home_page_info" 51 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 52 | return data -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/net_ease_cloud_music/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/net_ease_cloud_music/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/net_ease_cloud_music/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/net_ease_cloud_music/app/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/net_ease_cloud_music/app/net_ease_cloud_music_app_v1.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class NetEaseCloudMusicAppV1: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 获取单一歌曲信息V1(信息更全)| Fetch one music information V1 (more information) 14 | async def fetch_one_music_v1(self, music_id: str): 15 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_one_music_v1" 16 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 17 | return data 18 | 19 | # 获取单一歌曲信息V2(信息更少)| Fetch one music information V2 (less information) 20 | async def fetch_one_music_v2(self, music_id: str): 21 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_one_music_v2" 22 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 23 | return data 24 | 25 | # 获取单一歌曲歌词/Fetch one music lyric 26 | async def fetch_one_music_lyric(self, music_id: str): 27 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_one_music_lyric" 28 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 29 | return data 30 | 31 | # 获取单一歌曲播放地址V1(只能返回MP3格式,支持参数较少)/Fetch one music URL V1 (only MP3 format is supported, with fewer parameters) 32 | async def fetch_one_music_url_v1(self, music_id: str, br: str = "192000"): 33 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_one_music_url_v1" 34 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&br={br}") 35 | return data 36 | 37 | # 获取单一歌曲播放地址V2(支持更多参数)/Fetch one music URL V2 (support more parameters) 38 | async def fetch_one_music_url_v2(self, music_id: str, level: str = "exhigh", encodeType: str = "mp3"): 39 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_one_music_url_v2" 40 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&level={level}&encodeType={encodeType}") 41 | return data 42 | 43 | # Mlog(音乐视频)播放地址/Mlog (music video) playback address 44 | async def fetch_music_log_video_url(self, mlogId: str, resolution: str = "1080"): 45 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_music_log_video_url" 46 | data = await self.client.fetch_get_json(f"{endpoint}?mlogId={mlogId}&resolution={resolution}") 47 | return data 48 | 49 | # 获取歌曲评论/Fetch music comment 50 | async def fetch_music_comment(self, resource_id: str, beforeTime: str = "0", limit: str = "30"): 51 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_music_comment" 52 | data = await self.client.fetch_get_json( 53 | f"{endpoint}?resource_id={resource_id}&beforeTime={beforeTime}&limit={limit}") 54 | return data 55 | 56 | # 搜索接口V1/Search interface V1 57 | async def search_v1(self, keywords: str, offset: str = "0", limit: str = "20", _type: str = "1"): 58 | endpoint = "/api/v1/net_ease_cloud_music/app/search_v1" 59 | data = await self.client.fetch_get_json( 60 | f"{endpoint}?keywords={keywords}&offset={offset}&limit={limit}&type={_type}") 61 | return data 62 | 63 | # 获取用户歌单/Get user playlist 64 | async def fetch_user_playlist(self, uid: str, offset: str = "0", limit: str = "20"): 65 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_user_playlist" 66 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&offset={offset}&limit={limit}") 67 | return data 68 | 69 | # 获取用户信息/Get user information 70 | async def fetch_user_info(self, uid: str): 71 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_user_info" 72 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}") 73 | return data 74 | 75 | # 获取用户动态/Fetch user event 76 | async def fetch_user_event(self, uid: str, _time: str = "-1", limit: str = "10"): 77 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_user_event" 78 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&time={_time}&limit={limit}") 79 | return data 80 | 81 | # 获取用户粉丝列表/Fetch user followers 82 | async def fetch_user_followers(self, uid: str, lasttime: str = "0", pagesize: str = "20"): 83 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_user_followers" 84 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&lasttime={lasttime}&pagesize={pagesize}") 85 | return data 86 | 87 | # 获取用户关注列表/Fetch user follows 88 | async def fetch_user_follows(self, uid: str, offset: str = "0", limit: str = "20"): 89 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_user_follows" 90 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&offset={offset}&limit={limit}") 91 | return data 92 | 93 | # 获取歌手信息/Fetch artist detail 94 | async def fetch_artist_detail(self, artist_id: str): 95 | endpoint = "/api/v1/net_ease_cloud_music/app/fetch_artist_detail" 96 | data = await self.client.fetch_get_json(f"{endpoint}?artist_id={artist_id}") 97 | return data 98 | 99 | # 解密POST请求中的16进制payload/Decrypt the 16-bit payload in the POST request 100 | async def decrypt_post_payload(self, payload: str): 101 | endpoint = "/api/v1/net_ease_cloud_music/app/decrypt_post_payload" 102 | data = await self.client.fetch_post_json(endpoint, data=payload) 103 | return data 104 | 105 | # 加密POST请求中的payload并且返回16进制/Encrypt the payload in the POST request and return 16 hexadecimal 106 | async def encrypt_post_payload(self, uri: str, payload: dict, add_variable: bool = False): 107 | endpoint = "/api/v1/net_ease_cloud_music/app/encrypt_post_payload" 108 | endpoint = f"{endpoint}?uri={uri}&add_variable={add_variable}" 109 | data = await self.client.fetch_post_json(endpoint, data=json.dumps(payload)) 110 | return data 111 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/temp_mail/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/temp_mail/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/temp_mail/temp_mail_v1.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | 3 | from tikhub.http_client.api_client import APIClient 4 | 5 | 6 | class TempMailV1: 7 | # 初始化 | Initialize 8 | def __init__(self, client: APIClient): 9 | self.client = client 10 | 11 | # 获取一个临时邮箱 | Get a temporary email 12 | async def get_temp_email_address(self): 13 | endpoint = "/api/v1/temp_mail/v1/get_temp_email_address" 14 | data = await self.client.fetch_get_json(f"{endpoint}") 15 | return data 16 | 17 | # 获取邮件列表 | Get a list of emails 18 | async def get_emails_inbox(self, token: str): 19 | endpoint = "/api/v1/temp_mail/v1/get_emails_inbox" 20 | data = await self.client.fetch_get_json(f"{endpoint}?token={token}") 21 | return data 22 | 23 | # 通过邮件ID获取邮件数据 | Get email data by email ID 24 | async def get_email_by_id(self, token: str, message_id: str): 25 | endpoint = "/api/v1/temp_mail/v1/get_email_by_id" 26 | data = await self.client.fetch_get_json(f"{endpoint}?token={token}&message_id={message_id}") 27 | return data 28 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tikhub/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/tikhub/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tikhub/tikhub_user.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class TikHubUser: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 根据session_id获取用户信息 | Get TikHub user info 14 | async def get_user_info(self): 15 | endpoint = "/api/v1/tikhub/user/get_user_info" 16 | data = await self.client.fetch_get_json(endpoint) 17 | return data 18 | 19 | # 获取用户每日使用情况 | Get user daily usage 20 | async def get_user_daily_usage(self): 21 | endpoint = "/api/v1/tikhub/user/get_user_daily_usage" 22 | data = await self.client.fetch_get_json(endpoint) 23 | return data 24 | 25 | # 计算价格 | Calculate price 26 | async def calculate_price(self, endpoint: str, request_per_day: int): 27 | __endpoint = "/api/v1/tikhub/user/calculate_price" 28 | data = await self.client.fetch_get_json(f"{__endpoint}?endpoint={endpoint}&request_per_day={request_per_day}") 29 | return data 30 | 31 | # 获取阶梯式折扣百分比信息 | Get tiered discount percentage information 32 | async def get_tiered_discount_info(self): 33 | endpoint = "/api/v1/tikhub/user/get_tiered_discount_info" 34 | data = await self.client.fetch_get_json(endpoint) 35 | return data 36 | 37 | # 获取一个端点的信息 | Get information of an endpoint 38 | async def get_endpoint_info(self, endpoint: str): 39 | __endpoint = "/api/v1/tikhub/user/get_endpoint_info" 40 | data = await self.client.fetch_get_json(f"{__endpoint}?endpoint={endpoint}") 41 | return data 42 | 43 | # 获取所有端点信息 | Get all endpoints information 44 | async def get_all_endpoints_info(self): 45 | endpoint = "/api/v1/tikhub/user/get_all_endpoints_info" 46 | data = await self.client.fetch_get_json(endpoint) 47 | return data 48 | 49 | 50 | if __name__ == "__main__": 51 | import asyncio 52 | 53 | 54 | async def main(): 55 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 56 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 57 | 58 | tikhub_user = TikHubUser(client) 59 | 60 | # 根据session_id获取用户信息 | Get TikHub user info 61 | data = await tikhub_user.get_user_info() 62 | print(data) 63 | 64 | # 获取用户每日使用情况 | Get user daily usage 65 | data = await tikhub_user.get_user_daily_usage() 66 | print(data) 67 | 68 | # 计算价格 | Calculate price 69 | data = await tikhub_user.calculate_price(endpoint="/api/v1/douyin/app/v1/fetch_one_video", 70 | request_per_day=100000) 71 | print(data) 72 | 73 | # 获取阶梯式折扣百分比信息 | Get tiered discount percentage information 74 | data = await tikhub_user.get_tiered_discount_info() 75 | print(data) 76 | 77 | # 获取一个端点的信息 | Get information of an endpoint 78 | data = await tikhub_user.get_endpoint_info(endpoint="/api/v1/douyin/app/v1/fetch_one_video") 79 | print(data) 80 | 81 | # 获取所有端点信息 | Get all endpoints information 82 | data = await tikhub_user.get_all_endpoints_info() 83 | print(data) 84 | 85 | 86 | asyncio.run(main()) 87 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/tiktok/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/tiktok/app/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/app/tiktok_app_v2.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class TikTokAppV2: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 获取单个作品数据 | Get single video data 14 | async def fetch_one_video(self, aweme_id: int): 15 | endpoint = "/api/v1/tiktok/app/v2/fetch_one_video" 16 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}") 17 | return data 18 | 19 | # 根据分享链接获取作品数据 | Get video data by sharing url 20 | async def fetch_one_video_by_share_url(self, share_url: str): 21 | endpoint = "/api/v1/tiktok/app/v2/fetch_one_video_by_share_url" 22 | data = await self.client.fetch_get_json(f"{endpoint}?share_url={share_url}") 23 | return data 24 | 25 | # 获取指定用户的信息 | Get information of specified user 26 | async def handler_user_profile(self, sec_user_id: str): 27 | endpoint = "/api/v1/tiktok/app/v2/handler_user_profile" 28 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 29 | return data 30 | 31 | # 获取用户主页作品数据 | Get user homepage video data 32 | async def fetch_user_post_videos(self, sec_user_id: str, max_cursor: int, count: int): 33 | endpoint = "/api/v1/tiktok/app/v2/fetch_user_post_videos" 34 | data = await self.client.fetch_get_json( 35 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&count={count}") 36 | return data 37 | 38 | # 获取用户喜欢作品数据 | Get user like video data 39 | async def fetch_user_like_videos(self, sec_user_id: str, max_cursor: int, counts: int): 40 | endpoint = "/api/v1/tiktok/app/v2/fetch_user_like_videos" 41 | data = await self.client.fetch_get_json( 42 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&counts={counts}") 43 | return data 44 | 45 | # 获取单个视频评论数据 | Get single video comments data 46 | async def fetch_video_comments(self, aweme_id: str, cursor: int, count: int): 47 | endpoint = "/api/v1/tiktok/app/v2/fetch_video_comments" 48 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}") 49 | return data 50 | 51 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 52 | async def fetch_video_comments_reply(self, item_id: str, comment_id: str, cursor: int, count: int): 53 | endpoint = "/api/v1/tiktok/app/v2/fetch_video_comment_replies" 54 | data = await self.client.fetch_get_json( 55 | f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}") 56 | return data 57 | 58 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 59 | async def fetch_general_search_result(self, keyword: str, offset: int, count: int, sort_type: int, 60 | publish_time: int): 61 | endpoint = "/api/v1/tiktok/app/v2/fetch_general_search_result" 62 | data = await self.client.fetch_get_json( 63 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 64 | return data 65 | 66 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 67 | async def fetch_video_search_result(self, keyword: str, offset: int, count: int, sort_type: int, publish_time: int): 68 | endpoint = "/api/v1/tiktok/app/v2/fetch_video_search_result" 69 | data = await self.client.fetch_get_json( 70 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 71 | return data 72 | 73 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 74 | async def fetch_user_search_result(self, keyword: str, offset: int, count: int, user_search_follower_count: str, 75 | user_search_profile_type: str, user_search_other_pref: str): 76 | endpoint = "/api/v1/tiktok/app/v2/fetch_user_search_result" 77 | data = await self.client.fetch_get_json( 78 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&user_search_follower_count={user_search_follower_count}&user_search_profile_type={user_search_profile_type}&user_search_other_pref={user_search_other_pref}") 79 | return data 80 | 81 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 82 | async def fetch_music_search_result(self, keyword: str, offset: int, count: int): 83 | endpoint = "/api/v1/tiktok/app/v2/fetch_music_search_result" 84 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 85 | return data 86 | 87 | # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 88 | async def fetch_hashtag_search_result(self, keyword: str, offset: int, count: int): 89 | endpoint = "/api/v1/tiktok/app/v2/fetch_hashtag_search_result" 90 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 91 | return data 92 | 93 | # 获取指定关键词的直播搜索结果 | Get live search results of specified keywords 94 | async def fetch_live_search_result(self, keyword: str, offset: int, count: int): 95 | endpoint = "/api/v1/tiktok/app/v2/fetch_live_search_result" 96 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 97 | return data 98 | 99 | # 获取指定音乐的详情数据 | Get details of specified music 100 | async def fetch_music_detail(self, music_id: int): 101 | endpoint = "/api/v1/tiktok/app/v2/fetch_music_detail" 102 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 103 | return data 104 | 105 | # 抖音音乐视频列表结果 | Get video list of specified music 106 | async def fetch_music_video_list(self, music_id: int, cursor: int, count: int): 107 | endpoint = "/api/v1/tiktok/app/v2/fetch_music_video_list" 108 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&cursor={cursor}&count={count}") 109 | return data 110 | 111 | # 抖音话题详情数据 | Get details of specified hashtag 112 | async def fetch_hashtag_detail(self, ch_id: int): 113 | endpoint = "/api/v1/tiktok/app/v2/fetch_hashtag_detail" 114 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}") 115 | return data 116 | 117 | # 获取指定话题的作品数据 | Get video list of specified hashtag 118 | async def fetch_hashtag_post_list(self, ch_id: int, cursor: int, count: int): 119 | endpoint = "/api/v1/tiktok/app/v2/fetch_hashtag_video_list" 120 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}&cursor={cursor}&count={count}") 121 | return data 122 | 123 | # 获取指定用户的粉丝列表数据 | Get follower list of specified user 124 | async def fetch_user_follower_list(self, sec_user_id: str, count: int = 20, min_time: int = 0, page_token: str = ""): 125 | endpoint = "/api/v1/tiktok/app/v2/fetch_user_follower_list" 126 | data = await self.client.fetch_get_json( 127 | f"{endpoint}?sec_user_id={sec_user_id}&count={count}&min_time={min_time}&page_token={page_token}") 128 | return data 129 | 130 | # 获取指定用户的关注列表数据 | Get following list of specified user 131 | async def fetch_user_following_list(self, sec_user_id: str, count: int = 20, min_time: int = 0, page_token: str = ""): 132 | endpoint = "/api/v1/tiktok/app/v2/fetch_user_following_list" 133 | data = await self.client.fetch_get_json( 134 | f"{endpoint}?sec_user_id={sec_user_id}&count={count}&min_time={min_time}&page_token={page_token}") 135 | return data 136 | 137 | # 获取直播间排行榜数据 | Get live room ranking list 138 | async def fetch_live_ranking_list(self, room_id: str, anchor_id: str): 139 | endpoint = "/api/v1/tiktok/app/v2/fetch_live_ranking_list" 140 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}&anchor_id={anchor_id}") 141 | return data 142 | 143 | # 检测直播间是否在线 | Check if live room is online 144 | async def check_live_room_online(self, room_id: str): 145 | endpoint = "/api/v1/tiktok/app/v2/check_live_room_online" 146 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 147 | return data 148 | 149 | # 视频主页Feed (Home Feed) | Get video home feed 150 | async def fetch_home_feed(self): 151 | endpoint = "/api/v1/tiktok/app/v2/fetch_home_feed" 152 | data = await self.client.fetch_get_json(endpoint) 153 | return data 154 | 155 | 156 | if __name__ == "__main__": 157 | import asyncio 158 | 159 | 160 | async def main(): 161 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 162 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 163 | 164 | tiktok_app_v2 = TikTokAppV2(client) 165 | 166 | # 获取单个作品数据 | Get single video data 167 | data = await tiktok_app_v2.fetch_one_video(aweme_id=6953882931123590914) 168 | print(data) 169 | 170 | # 获取指定用户的信息 | Get information of specified user 171 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 172 | data = await tiktok_app_v2.handler_user_profile(sec_user_id) 173 | print(data) 174 | 175 | # 获取用户主页作品数据 | Get user homepage video data 176 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 177 | data = await tiktok_app_v2.fetch_user_post_videos(sec_user_id, max_cursor=0, count=10) 178 | print(data) 179 | 180 | # 获取用户喜欢作品数据 | Get user like video data 181 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 182 | data = await tiktok_app_v2.fetch_user_like_videos(sec_user_id, max_cursor=0, counts=10) 183 | print(data) 184 | 185 | # 获取单个视频评论数据 | Get single video comments data 186 | aweme_id = "6953882931123590914" 187 | data = await tiktok_app_v2.fetch_video_comments(aweme_id, cursor=0, count=10) 188 | print(data) 189 | 190 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 191 | item_id = "6953882931123590914" 192 | comment_id = "6953882931123590914" 193 | data = await tiktok_app_v2.fetch_video_comments_reply(item_id, comment_id, cursor=0, count=10) 194 | print(data) 195 | 196 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 197 | keyword = "抖音" 198 | offset = 0 199 | count = 10 200 | sort_type = 0 201 | publish_time = 0 202 | data = await tiktok_app_v2.fetch_general_search_result(keyword, offset, count, sort_type, publish_time) 203 | print(data) 204 | 205 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 206 | keyword = "抖音" 207 | offset = 0 208 | count = 10 209 | sort_type = 0 210 | publish_time = 0 211 | data = await tiktok_app_v2.fetch_video_search_result(keyword, offset, count, sort_type, publish_time) 212 | print(data) 213 | 214 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 215 | keyword = "抖音" 216 | offset = 0 217 | count = 10 218 | user_search_follower_count = "0" 219 | user_search_profile_type = "0" 220 | user_search_other_pref = "0" 221 | data = await tiktok_app_v2.fetch_user_search_result(keyword, offset, count, user_search_follower_count, user_search_profile_type, user_search_other_pref) 222 | print(data) 223 | 224 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 225 | keyword = "抖音" 226 | offset = 0 227 | count = 10 228 | data = await tiktok_app_v2.fetch_music_search_result(keyword, offset, count) 229 | print(data) 230 | 231 | # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 232 | keyword = "抖音" 233 | offset = 0 234 | count = 10 235 | data = await tiktok_app_v2.fetch_hashtag_search_result(keyword, offset, count) 236 | print(data) 237 | 238 | # 获取指定关键词的直播搜索结果 | Get live search results of specified keywords 239 | keyword = "抖音" 240 | offset = 0 241 | count = 10 242 | data = await tiktok_app_v2.fetch_live_search_result(keyword, offset, count) 243 | print(data) 244 | 245 | # 获取指定音乐的详情数据 | Get details of specified music 246 | music_id = 6953882931123590914 247 | data = await tiktok_app_v2.fetch_music_detail(music_id) 248 | print(data) 249 | 250 | # 抖音音乐视频列表结果 | Get video list of specified music 251 | music_id = 6953882931123590914 252 | cursor = 0 253 | count = 10 254 | data = await tiktok_app_v2.fetch_music_video_list(music_id, cursor, count) 255 | print(data) 256 | 257 | # 抖音话题详情数据 | Get details of specified hashtag 258 | ch_id = 6953882931123590914 259 | data = await tiktok_app_v2.fetch_hashtag_detail(ch_id) 260 | print(data) 261 | 262 | # 获取指定话题的作品数据 | Get video list of specified hashtag 263 | ch_id = 6953882931123590914 264 | cursor = 0 265 | count = 10 266 | data = await tiktok_app_v2.fetch_hashtag_post_list(ch_id, cursor, count) 267 | print(data) 268 | 269 | # 获取指定用户的粉丝列表数据 | Get follower list of specified user 270 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 271 | count = 10 272 | max_time = 0 273 | data = await tiktok_app_v2.fetch_user_follower_list(sec_user_id, count, max_time) 274 | print(data) 275 | 276 | # 获取指定用户的关注列表数据 | Get following list of specified user 277 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 278 | count = 10 279 | max_time = 0 280 | data = await tiktok_app_v2.fetch_user_following_list(sec_user_id, count, max_time) 281 | print(data) 282 | 283 | # 获取直播间排行榜数据 | Get live room ranking list 284 | room_id = "6953882931123590914" 285 | anchor_id = "6953882931123590914" 286 | data = await tiktok_app_v2.fetch_live_ranking_list(room_id, anchor_id) 287 | print(data) 288 | 289 | # 检测直播间是否在线 | Check if live room is online 290 | room_id = "6953882931123590914" 291 | data = await tiktok_app_v2.check_live_room_online(room_id) 292 | print(data) 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/app/tiktok_app_v3.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | from typing import List 4 | 5 | from tikhub.http_client.api_client import APIClient 6 | 7 | 8 | class TikTokAppV3: 9 | 10 | # 初始化 | Initialize 11 | def __init__(self, client: APIClient): 12 | self.client = client 13 | 14 | # 获取单个作品数据 | Get single video data 15 | async def fetch_one_video(self, aweme_id: int): 16 | endpoint = "/api/v1/tiktok/app/v3/fetch_one_video" 17 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}") 18 | return data 19 | 20 | # 批量获取视频信息 (Batch Get Video Information) 21 | async def fetch_multi_video(self, aweme_ids: List[str]): 22 | endpoint = f"/api/v1/tiktok/app/v3/fetch_multi_video" 23 | data = await self.client.fetch_post_json(endpoint, params={"aweme_ids": aweme_ids}) 24 | return data 25 | 26 | # 根据分享链接获取作品数据 | Get video data by sharing url 27 | async def fetch_one_video_by_share_url(self, share_url: str): 28 | endpoint = "/api/v1/tiktok/app/v3/fetch_one_video_by_share_url" 29 | data = await self.client.fetch_get_json(f"{endpoint}?share_url={share_url}") 30 | return data 31 | 32 | # 获取指定用户的信息 | Get information of specified user 33 | async def handler_user_profile(self, sec_user_id: str): 34 | endpoint = "/api/v1/tiktok/app/v3/handler_user_profile" 35 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 36 | return data 37 | 38 | # 获取用户转发的作品数据 | Get user repost video data 39 | async def fetch_user_repost_videos(self, user_id: int, offset: int, count: int): 40 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_repost_videos" 41 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&offset={offset}&count={count}") 42 | return data 43 | 44 | # 获取用户主页作品数据 | Get user homepage video data 45 | async def fetch_user_post_videos(self, sec_user_id: str, max_cursor: int, count: int): 46 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_post_videos" 47 | data = await self.client.fetch_get_json( 48 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&count={count}") 49 | return data 50 | 51 | # 获取用户喜欢作品数据 | Get user like video data 52 | async def fetch_user_like_videos(self, sec_user_id: str, max_cursor: int, counts: int): 53 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_like_videos" 54 | data = await self.client.fetch_get_json( 55 | f"{endpoint}?sec_user_id={sec_user_id}&max_cursor={max_cursor}&counts={counts}") 56 | return data 57 | 58 | # 获取单个视频评论数据 | Get single video comments data 59 | async def fetch_video_comments(self, aweme_id: str, cursor: int, count: int): 60 | endpoint = "/api/v1/tiktok/app/v3/fetch_video_comments" 61 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}") 62 | return data 63 | 64 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 65 | async def fetch_video_comments_reply(self, item_id: str, comment_id: str, cursor: int, count: int): 66 | endpoint = "/api/v1/tiktok/app/v3/fetch_video_comment_replies" 67 | data = await self.client.fetch_get_json( 68 | f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}") 69 | return data 70 | 71 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 72 | async def fetch_general_search_result(self, keyword: str, offset: int, count: int, sort_type: int, 73 | publish_time: int): 74 | endpoint = "/api/v1/tiktok/app/v3/fetch_general_search_result" 75 | data = await self.client.fetch_get_json( 76 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 77 | return data 78 | 79 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 80 | async def fetch_video_search_result(self, keyword: str, offset: int, count: int, sort_type: int, publish_time: int): 81 | endpoint = "/api/v1/tiktok/app/v3/fetch_video_search_result" 82 | data = await self.client.fetch_get_json( 83 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&sort_type={sort_type}&publish_time={publish_time}") 84 | return data 85 | 86 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 87 | async def fetch_user_search_result(self, keyword: str, offset: int, count: int, user_search_follower_count: str, 88 | user_search_profile_type: str, user_search_other_pref: str): 89 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_search_result" 90 | data = await self.client.fetch_get_json( 91 | f"{endpoint}?keyword={keyword}&offset={offset}&count={count}&user_search_follower_count={user_search_follower_count}&user_search_profile_type={user_search_profile_type}&user_search_other_pref={user_search_other_pref}") 92 | return data 93 | 94 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 95 | async def fetch_music_search_result(self, keyword: str, offset: int, count: int): 96 | endpoint = "/api/v1/tiktok/app/v3/fetch_music_search_result" 97 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 98 | return data 99 | 100 | # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 101 | async def fetch_hashtag_search_result(self, keyword: str, offset: int, count: int): 102 | endpoint = "/api/v1/tiktok/app/v3/fetch_hashtag_search_result" 103 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 104 | return data 105 | 106 | # 获取指定关键词的直播搜索结果 | Get live search results of specified keywords 107 | async def fetch_live_search_result(self, keyword: str, offset: int, count: int): 108 | endpoint = "/api/v1/tiktok/app/v3/fetch_live_search_result" 109 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 110 | return data 111 | 112 | # 获取指定音乐的详情数据 | Get details of specified music 113 | async def fetch_music_detail(self, music_id: int): 114 | endpoint = "/api/v1/tiktok/app/v3/fetch_music_detail" 115 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}") 116 | return data 117 | 118 | # 抖音音乐视频列表结果 | Get video list of specified music 119 | async def fetch_music_video_list(self, music_id: int, cursor: int, count: int): 120 | endpoint = "/api/v1/tiktok/app/v3/fetch_music_video_list" 121 | data = await self.client.fetch_get_json(f"{endpoint}?music_id={music_id}&cursor={cursor}&count={count}") 122 | return data 123 | 124 | # 抖音话题详情数据 | Get details of specified hashtag 125 | async def fetch_hashtag_detail(self, ch_id: int): 126 | endpoint = "/api/v1/tiktok/app/v3/fetch_hashtag_detail" 127 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}") 128 | return data 129 | 130 | # 获取指定话题的作品数据 | Get video list of specified hashtag 131 | async def fetch_hashtag_video_list(self, ch_id: int, cursor: int, count: int): 132 | endpoint = "/api/v1/tiktok/app/v3/fetch_hashtag_video_list" 133 | data = await self.client.fetch_get_json(f"{endpoint}?ch_id={ch_id}&cursor={cursor}&count={count}") 134 | return data 135 | 136 | # 获取指定用户的粉丝列表数据 | Get follower list of specified user 137 | async def fetch_user_follower_list(self, sec_user_id: str, count: int = 20, min_time: int = 0, page_token: str = ""): 138 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_follower_list" 139 | data = await self.client.fetch_get_json( 140 | f"{endpoint}?sec_user_id={sec_user_id}&count={count}&min_time={min_time}&page_token={page_token}") 141 | return data 142 | 143 | # 获取指定用户的关注列表数据 | Get following list of specified user 144 | async def fetch_user_following_list(self, sec_user_id: str, count: int = 20, min_time: int = 0, page_token: str = ""): 145 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_following_list" 146 | data = await self.client.fetch_get_json( 147 | f"{endpoint}?sec_user_id={sec_user_id}&count={count}&min_time={min_time}&page_token={page_token}") 148 | return data 149 | 150 | # 获取指定直播间的数据 | Get data of specified live room 151 | async def fetch_live_room_info(self, room_id: str): 152 | endpoint = "/api/v1/tiktok/app/v3/fetch_live_room_info" 153 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 154 | return data 155 | 156 | # TikTok直播间排行榜 | Get live room ranking list 157 | async def fetch_live_room_rank_list(self, room_id: str, anchor_id: str): 158 | endpoint = "/api/v1/tiktok/app/v3/fetch_live_ranking_list" 159 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}&anchor_id={anchor_id}") 160 | return data 161 | 162 | # 检测直播间是否在线 | Check if live room is online 163 | async def fetch_live_room_check(self, room_id: str): 164 | endpoint = "/api/v1/tiktok/app/v3/check_live_room_online" 165 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 166 | return data 167 | 168 | # 获取分享短链接 | Get share short link 169 | async def fetch_share_short_link(self, url: str): 170 | endpoint = "/api/v1/tiktok/app/v3/fetch_share_short_link" 171 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 172 | return data 173 | 174 | # 获取分享二维码 | Get share QR code 175 | async def fetch_share_qr_code(self, url: str): 176 | endpoint = "/api/v1/tiktok/app/v3/fetch_share_qr_code" 177 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 178 | return data 179 | 180 | # 获取地点搜索结果 | Get location search results 181 | async def fetch_location_search(self, keyword: str, offset: int, count: int): 182 | endpoint = "/api/v1/tiktok/app/v3/fetch_location_search" 183 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&count={count}") 184 | return data 185 | 186 | # 获取商品搜索结果 | Get product search results 187 | async def fetch_product_search(self, keyword: str, cursor: int, count: int, sort_type: int, 188 | customer_review_four_star: bool, have_discount: bool, min_price: str, 189 | max_price: str): 190 | endpoint = "/api/v1/tiktok/app/v3/fetch_product_search" 191 | data = await self.client.fetch_get_json( 192 | f"{endpoint}?keyword={keyword}&cursor={cursor}&count={count}&sort_type={sort_type}&customer_review_four_star={customer_review_four_star}&have_discount={have_discount}&min_price={min_price}&max_price={max_price}") 193 | return data 194 | 195 | # 获取商品详情数据 | Get product detail data 196 | async def fetch_product_detail(self, product_id: str): 197 | endpoint = "/api/v1/tiktok/app/v3/fetch_product_detail" 198 | data = await self.client.fetch_get_json(f"{endpoint}?product_id={product_id}") 199 | return data 200 | 201 | # 获取商品评价数据 | Get product review data 202 | async def fetch_product_review(self, product_id: str, cursor: int, size: int, filter_id: int, sort_type: int): 203 | endpoint = "/api/v1/tiktok/app/v3/fetch_product_review" 204 | data = await self.client.fetch_get_json( 205 | f"{endpoint}?product_id={product_id}&cursor={cursor}&size={size}&filter_id={filter_id}&sort_type={sort_type}") 206 | return data 207 | 208 | # 获取商家主页Page列表数据 | Get shop home page list data 209 | async def fetch_shop_home_page_list(self, sec_user_id: str): 210 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_home_page_list" 211 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}") 212 | return data 213 | 214 | # 获取商家主页数据 | Get shop home page data 215 | async def fetch_shop_home(self, page_id: str, seller_id: str): 216 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_home" 217 | data = await self.client.fetch_get_json(f"{endpoint}?page_id={page_id}&seller_id={seller_id}") 218 | return data 219 | 220 | # 获取商家商品推荐数据 | Get shop product recommend data 221 | async def fetch_shop_product_recommend(self, seller_id: str, scroll_param: str, page_size: int): 222 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_product_recommend" 223 | data = await self.client.fetch_get_json( 224 | f"{endpoint}?seller_id={seller_id}&scroll_param={scroll_param}&page_size={page_size}") 225 | return data 226 | 227 | # 获取商家商品列表数据 | Get shop product list data 228 | async def fetch_shop_product_list(self, seller_id: str, scroll_params: str, page_size: int, sort_field: int, 229 | sort_order: int): 230 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_product_list" 231 | data = await self.client.fetch_get_json( 232 | f"{endpoint}?seller_id={seller_id}&scroll_params={scroll_params}&page_size={page_size}&sort_field={sort_field}&sort_order={sort_order}") 233 | return data 234 | 235 | # 获取商家信息数据 | Get shop information data 236 | async def fetch_shop_info(self, shop_id: str): 237 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_info" 238 | data = await self.client.fetch_get_json(f"{endpoint}?shop_id={shop_id}") 239 | return data 240 | 241 | # 获取商家产品分类数据 | Get shop product category data 242 | async def fetch_shop_product_category(self, seller_id: str): 243 | endpoint = "/api/v1/tiktok/app/v3/fetch_shop_product_category" 244 | data = await self.client.fetch_get_json(f"{endpoint}?seller_id={seller_id}") 245 | return data 246 | 247 | # 获取直播每日榜单数据 | Get live daily rank data 248 | async def fetch_live_daily_rank(self): 249 | endpoint = "/api/v1/tiktok/app/v3/fetch_live_daily_rank" 250 | data = await self.client.fetch_get_json(endpoint) 251 | return data 252 | 253 | # 获取用户音乐列表数据 | Get user music list data 254 | async def fetch_user_music_list(self, sec_user_id: str, cursor: int, count: int): 255 | endpoint = "/api/v1/tiktok/app/v3/fetch_user_music_list" 256 | data = await self.client.fetch_get_json(f"{endpoint}?sec_user_id={sec_user_id}&cursor={cursor}&count={count}") 257 | return data 258 | 259 | # 视频主页Feed (Home Feed) | Get video home feed 260 | async def fetch_home_feed(self): 261 | endpoint = "/api/v1/tiktok/app/v3/fetch_home_feed" 262 | data = await self.client.fetch_get_json(endpoint) 263 | return data 264 | 265 | # TikTok APP注册设备信息 | Register device information 266 | async def register_device_info(self, proxy: str = ''): 267 | endpoint = "/api/v1/tiktok/app/v3/register_device_info" 268 | data = await self.client.fetch_get_json(f"{endpoint}?proxy={proxy}") 269 | return data 270 | 271 | 272 | if __name__ == "__main__": 273 | import asyncio 274 | 275 | 276 | async def main(): 277 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 278 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 279 | 280 | tiktok_app_v3 = TikTokAppV3(client) 281 | 282 | # 获取单个作品数据 | Get single video data 283 | aweme_id = 6953663666666666666 284 | data = await tiktok_app_v3.fetch_one_video(aweme_id) 285 | print(data) 286 | 287 | # 获取指定用户的信息 | Get information of specified user 288 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 289 | data = await tiktok_app_v3.handler_user_profile(sec_user_id) 290 | print(data) 291 | 292 | # 获取用户主页作品数据 | Get user homepage video data 293 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 294 | max_cursor = 0 295 | count = 30 296 | data = await tiktok_app_v3.fetch_user_post_videos(sec_user_id, max_cursor, count) 297 | print(data) 298 | 299 | # 获取用户喜欢作品数据 | Get user like video data 300 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 301 | max_cursor = 0 302 | counts = 30 303 | data = await tiktok_app_v3.fetch_user_like_videos(sec_user_id, max_cursor, counts) 304 | print(data) 305 | 306 | # 获取单个视频评论数据 | Get single video comments data 307 | aweme_id = "6953663666666666666" 308 | cursor = 0 309 | count = 30 310 | data = await tiktok_app_v3.fetch_video_comments(aweme_id, cursor, count) 311 | print(data) 312 | 313 | # 获取指定视频的评论回复数据 | Get comment replies data of specified video 314 | item_id = "6953663666666666666" 315 | comment_id = "6953663666666666666" 316 | cursor = 0 317 | count = 30 318 | data = await tiktok_app_v3.fetch_video_comments_reply(item_id, comment_id, cursor, count) 319 | print(data) 320 | 321 | # 获取指定关键词的综合搜索结果 | Get comprehensive search results of specified keywords 322 | keyword = "tiktok" 323 | offset = 0 324 | count = 30 325 | sort_type = 0 326 | publish_time = 0 327 | data = await tiktok_app_v3.fetch_general_search_result(keyword, offset, count, sort_type, publish_time) 328 | print(data) 329 | 330 | # 获取指定关键词的视频搜索结果 | Get video search results of specified keywords 331 | keyword = "tiktok" 332 | offset = 0 333 | count = 30 334 | sort_type = 0 335 | publish_time = 0 336 | data = await tiktok_app_v3.fetch_video_search_result(keyword, offset, count, sort_type, publish_time) 337 | print(data) 338 | 339 | # 获取指定关键词的用户搜索结果 | Get user search results of specified keywords 340 | keyword = "tiktok" 341 | offset = 0 342 | count = 30 343 | user_search_follower_count = "" 344 | user_search_profile_type = "" 345 | user_search_other_pref = "" 346 | data = await tiktok_app_v3.fetch_user_search_result(keyword, offset, count, user_search_follower_count, 347 | user_search_profile_type, user_search_other_pref) 348 | print(data) 349 | 350 | # 获取指定关键词的音乐搜索结果 | Get music search results of specified keywords 351 | keyword = "tiktok" 352 | offset = 0 353 | count = 30 354 | data = await tiktok_app_v3.fetch_music_search_result(keyword, offset, count) 355 | print(data) 356 | 357 | # 获取指定关键词的话题搜索结果 | Get hashtag search results of specified keywords 358 | keyword = "tiktok" 359 | offset = 0 360 | count = 30 361 | data = await tiktok_app_v3.fetch_hashtag_search_result(keyword, offset, count) 362 | print(data) 363 | 364 | # 获取指定关键词的直播搜索结果 | Get live search results of specified keywords 365 | keyword = "tiktok" 366 | offset = 0 367 | count = 30 368 | data = await tiktok_app_v3.fetch_live_search_result(keyword, offset, count) 369 | print(data) 370 | 371 | # 获取指定音乐的详情数据 | Get details of specified music 372 | music_id = 6953663666666666666 373 | data = await tiktok_app_v3.fetch_music_detail(music_id) 374 | print(data) 375 | 376 | # 抖音音乐视频列表结果 | Get video list of specified music 377 | music_id = 6953663666666666666 378 | cursor = 0 379 | count = 30 380 | data = await tiktok_app_v3.fetch_music_video_list(music_id, cursor, count) 381 | print(data) 382 | 383 | # 抖音话题详情数据 | Get details of specified hashtag 384 | ch_id = 6953663666666666666 385 | data = await tiktok_app_v3.fetch_hashtag_detail(ch_id) 386 | print(data) 387 | 388 | # 获取指定话题的作品数据 | Get video list of specified hashtag 389 | ch_id = 6953663666666666666 390 | cursor = 0 391 | count = 30 392 | data = await tiktok_app_v3.fetch_hashtag_video_list(ch_id, cursor, count) 393 | print(data) 394 | 395 | # 获取指定用户的粉丝列表数据 | Get follower list of specified user 396 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 397 | count = 30 398 | max_time = 0 399 | data = await tiktok_app_v3.fetch_user_follower_list(sec_user_id, count, max_time) 400 | print(data) 401 | 402 | # 获取指定用户的关注列表数据 | Get following list of specified user 403 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 404 | count = 30 405 | max_time = 0 406 | data = await tiktok_app_v3.fetch_user_following_list(sec_user_id, count, max_time) 407 | print(data) 408 | 409 | # TikTok直播间排行榜 | Get live room ranking list 410 | room_id = "6953663666666666666" 411 | anchor_id = "6953663666666666666" 412 | data = await tiktok_app_v3.fetch_live_room_rank_list(room_id, anchor_id) 413 | print(data) 414 | 415 | # 检测直播间是否在线 | Check if live room is online 416 | room_id = "6953663666666666666" 417 | data = await tiktok_app_v3.fetch_live_room_check(room_id) 418 | print(data) 419 | 420 | # 获取分享短链接 | Get share short link 421 | url = "https://www.tiktok.com/@tiktok" 422 | data = await tiktok_app_v3.fetch_share_short_link(url) 423 | print(data) 424 | 425 | # 获取分享二维码 | Get share QR code 426 | url = "https://www.tiktok.com/@tiktok" 427 | data = await tiktok_app_v3.fetch_share_qr_code(url) 428 | print(data) 429 | 430 | # 获取地点搜索结果 | Get location search results 431 | keyword = "tiktok" 432 | offset = 0 433 | count = 30 434 | data = await tiktok_app_v3.fetch_location_search(keyword, offset, count) 435 | print(data) 436 | 437 | # 获取商品搜索结果 | Get product search results 438 | keyword = "tiktok" 439 | cursor = 0 440 | count = 30 441 | sort_type = 0 442 | customer_review_four_star = False 443 | have_discount = False 444 | min_price = "0" 445 | max_price = "1000" 446 | data = await tiktok_app_v3.fetch_product_search(keyword, cursor, count, sort_type, customer_review_four_star, 447 | have_discount, min_price, max_price) 448 | print(data) 449 | 450 | # 获取商品详情数据 | Get product detail data 451 | product_id = "6953663666666666666" 452 | data = await tiktok_app_v3.fetch_product_detail(product_id) 453 | print(data) 454 | 455 | # 获取商品评价数据 | Get product review data 456 | product_id = "6953663666666666666" 457 | cursor = 0 458 | size = 30 459 | filter_id = 0 460 | sort_type = 0 461 | data = await tiktok_app_v3.fetch_product_review(product_id, cursor, size, filter_id, sort_type) 462 | print(data) 463 | 464 | # 获取商家主页Page列表数据 | Get shop home page list data 465 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 466 | data = await tiktok_app_v3.fetch_shop_home_page_list(sec_user_id) 467 | print(data) 468 | 469 | # 获取商家主页数据 | Get shop home page data 470 | page_id = "6953663666666666666" 471 | seller_id = "6953663666666666666" 472 | data = await tiktok_app_v3.fetch_shop_home(page_id, seller_id) 473 | print(data) 474 | 475 | # 获取商家商品推荐数据 | Get shop product recommend data 476 | seller_id = "6953663666666666666" 477 | scroll_param = "6953663666666666666" 478 | page_size = 30 479 | data = await tiktok_app_v3.fetch_shop_product_recommend(seller_id, scroll_param, page_size) 480 | print(data) 481 | 482 | # 获取商家商品列表数据 | Get shop product list data 483 | seller_id = "6953663666666666666" 484 | scroll_params = "6953663666666666666" 485 | page_size = 30 486 | sort_field = 0 487 | sort_order = 0 488 | data = await tiktok_app_v3.fetch_shop_product_list(seller_id, scroll_params, page_size, sort_field, sort_order) 489 | print(data) 490 | 491 | # 获取商家信息数据 | Get shop information data 492 | shop_id = "6953663666666666666" 493 | data = await tiktok_app_v3.fetch_shop_info(shop_id) 494 | print(data) 495 | 496 | # 获取商家产品分类数据 | Get shop product category data 497 | seller_id = "6953663666666666666" 498 | data = await tiktok_app_v3.fetch_shop_product_category(seller_id) 499 | print(data) 500 | 501 | # 获取直播每日榜单数据 | Get live daily rank data 502 | data = await tiktok_app_v3.fetch_live_daily_rank() 503 | print(data) 504 | 505 | # 获取用户音乐列表数据 | Get user music list data 506 | sec_user_id = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 507 | cursor = 0 508 | count = 30 509 | data = await tiktok_app_v3.fetch_user_music_list(sec_user_id, cursor, count) 510 | print(data) 511 | 512 | 513 | asyncio.run(main()) 514 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/tiktok/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/tiktok/web/tiktok_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | import websockets 5 | 6 | from tikhub.http_client.api_client import APIClient 7 | 8 | 9 | class TikTokWeb: 10 | 11 | # 初始化 | Initialize 12 | def __init__(self, client: APIClient): 13 | self.client = client 14 | 15 | # 获取单个作品数据 | Get single video data 16 | async def fetch_post_detail(self, item_id: str): 17 | endpoint = "/api/v1/tiktok/web/fetch_post_detail" 18 | data = await self.client.fetch_get_json(f"{endpoint}?itemId={item_id}") 19 | return data 20 | 21 | # 获取用户的个人信息 | Get user profile 22 | async def fetch_user_profile(self, secUid: str, uniqueId: str = None): 23 | endpoint = "/api/v1/tiktok/web/fetch_user_profile" 24 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&uniqueId={uniqueId}") 25 | return data 26 | 27 | # 获取用户的作品列表 | Get user posts 28 | async def fetch_user_post(self, secUid: str, cursor: int, count: int, coverFormat: int): 29 | endpoint = "/api/v1/tiktok/web/fetch_user_post" 30 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&cursor={cursor}&count={count}&coverFormat={coverFormat}") 31 | return data 32 | 33 | # 获取用户的点赞列表 | Get user likes 34 | async def fetch_user_like(self, secUid: str, cursor: int, count: int, coverFormat: int): 35 | endpoint = "/api/v1/tiktok/web/fetch_user_like" 36 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&cursor={cursor}&count={count}&coverFormat={coverFormat}") 37 | return data 38 | 39 | # 获取用户的收藏列表 | Get user favorites 40 | async def fetch_user_collect(self, cookie: str, secUid: str, cursor: int, count: int, coverFormat: int): 41 | endpoint = "/api/v1/tiktok/web/fetch_user_collect" 42 | data = await self.client.fetch_get_json(f"{endpoint}?cookie={cookie}&secUid={secUid}&cursor={cursor}&count={count}&coverFormat={coverFormat}") 43 | return data 44 | 45 | # 获取用户的播放列表 | Get user play list 46 | async def fetch_user_play_list(self, secUid: str, cursor: int, count: int): 47 | endpoint = "/api/v1/tiktok/web/fetch_user_play_list" 48 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&cursor={cursor}&count={count}") 49 | return data 50 | 51 | # 获取用户的合辑列表 | Get user mix list 52 | async def fetch_user_mix(self, mixId: str, cursor: int, count: int): 53 | endpoint = "/api/v1/tiktok/web/fetch_user_mix" 54 | data = await self.client.fetch_get_json(f"{endpoint}?mixId={mixId}&cursor={cursor}&count={count}") 55 | return data 56 | 57 | # 获取作品的评论列表 | Get video comments 58 | async def fetch_post_comment(self, aweme_id: str, cursor: int, count: int, current_region: str): 59 | endpoint = "/api/v1/tiktok/web/fetch_post_comment" 60 | data = await self.client.fetch_get_json(f"{endpoint}?aweme_id={aweme_id}&cursor={cursor}&count={count}¤t_region={current_region}") 61 | return data 62 | 63 | # 获取作品的评论回复列表 | Get video comment replies 64 | async def fetch_post_comment_reply(self, item_id: str, comment_id: str, cursor: int, count: int, current_region: str): 65 | endpoint = "/api/v1/tiktok/web/fetch_post_comment_reply" 66 | data = await self.client.fetch_get_json(f"{endpoint}?item_id={item_id}&comment_id={comment_id}&cursor={cursor}&count={count}¤t_region={current_region}") 67 | return data 68 | 69 | # 获取用户的粉丝列表 | Get user followers 70 | async def fetch_user_fans(self, secUid: str, count: int, maxCursor: int, minCursor: int): 71 | endpoint = "/api/v1/tiktok/web/fetch_user_fans" 72 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&count={count}&maxCursor={maxCursor}&minCursor={minCursor}") 73 | return data 74 | 75 | # 获取用户的关注列表 | Get user followings 76 | async def fetch_user_follow(self, secUid: str, count: int, maxCursor: int, minCursor: int): 77 | endpoint = "/api/v1/tiktok/web/fetch_user_follow" 78 | data = await self.client.fetch_get_json(f"{endpoint}?secUid={secUid}&count={count}&maxCursor={maxCursor}&minCursor={minCursor}") 79 | return data 80 | 81 | # 获取综合搜索列表 | Get general search list 82 | async def fetch_general_search(self, keyword: str, count: int, offset: int, search_id: str = None, cookie: str = None): 83 | endpoint = "/api/v1/tiktok/web/fetch_general_search" 84 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&count={count}&offset={offset}&search_id={search_id}&cookie={cookie}") 85 | return data 86 | 87 | # 搜索关键字推荐 | Search keyword suggest 88 | async def fetch_search_keyword_suggest(self, keyword: str): 89 | endpoint = "/api/v1/tiktok/web/fetch_search_keyword_suggest" 90 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}") 91 | return data 92 | 93 | # 搜索用户 | Search user 94 | async def fetch_search_user(self, keyword: str, cursor: int, search_id: str = None, cookie: str = None): 95 | endpoint = "/api/v1/tiktok/web/fetch_search_user" 96 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&cursor={cursor}&search_id={search_id}&cookie={cookie}") 97 | return data 98 | 99 | # 搜索视频 | Search video 100 | async def fetch_search_video(self, keyword: str, count: int, offset: int, search_id: str = None, cookie: str = None): 101 | endpoint = "/api/v1/tiktok/web/fetch_search_video" 102 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&count={count}&offset={offset}&search_id={search_id}&cookie={cookie}") 103 | return data 104 | 105 | # 搜索直播 | Search live 106 | async def fetch_search_live(self, keyword: str, count: int, offset: int, search_id: str = None, cookie: str = None): 107 | endpoint = "/api/v1/tiktok/web/fetch_search_live" 108 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&count={count}&offset={offset}&search_id={search_id}&cookie={cookie}") 109 | return data 110 | 111 | # Tag详情 | Tag detail 112 | async def fetch_tag_detail(self, tag_name: str): 113 | endpoint = "/api/v1/tiktok/web/fetch_tag_detail" 114 | data = await self.client.fetch_get_json(f"{endpoint}?tag_name={tag_name}") 115 | return data 116 | 117 | # Tag作品列表 | Tag post list 118 | async def fetch_tag_post(self, challengeID: str, cursor: int, count: int): 119 | endpoint = "/api/v1/tiktok/web/fetch_tag_post" 120 | data = await self.client.fetch_get_json(f"{endpoint}?challengeID={challengeID}&cursor={cursor}&count={count}") 121 | return data 122 | 123 | # 生成真实msToken | Generate real msToken 124 | async def fetch_real_msToken(self): 125 | endpoint = "/api/v1/tiktok/web/generate_real_msToken" 126 | data = await self.client.fetch_get_json(endpoint) 127 | return data 128 | 129 | # 生成ttwid | Generate ttwid 130 | async def fetch_ttwid(self, cookie: str): 131 | endpoint = "/api/v1/tiktok/web/generate_ttwid" 132 | data = await self.client.fetch_get_json(f"{endpoint}?cookie={cookie}") 133 | return data 134 | 135 | # 生成xbogus | Generate xbogus 136 | async def gen_xbogus(self, url: str, user_agent: str): 137 | endpoint = "/api/v1/tiktok/web/generate_xbogus" 138 | data = await self.client.fetch_post_json(endpoint, data={"url": url, "user_agent": user_agent}) 139 | return data 140 | 141 | # 提取用户sec_user_id | Extract user sec_user_id 142 | async def get_sec_user_id(self, url: str): 143 | endpoint = "/api/v1/tiktok/web/get_sec_user_id" 144 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 145 | return data 146 | 147 | # 提取列表用户sec_user_id | Extract list user sec_user_id 148 | async def get_all_sec_user_id(self, url: list): 149 | endpoint = "/api/v1/tiktok/web/get_all_sec_user_id" 150 | data = await self.client.fetch_post_json(endpoint, data={"url": url}) 151 | return data 152 | 153 | # 提取单个作品id | Extract single video id 154 | async def get_aweme_id(self, url: str): 155 | endpoint = "/api/v1/tiktok/web/get_aweme_id" 156 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 157 | return data 158 | 159 | # 提取列表作品id | Extract list video id 160 | async def get_all_aweme_id(self, url: list): 161 | endpoint = "/api/v1/tiktok/web/get_all_aweme_id" 162 | data = await self.client.fetch_post_json(endpoint, data={"url": url}) 163 | return data 164 | 165 | # 获取用户unique_id | Get user unique_id 166 | async def get_unique_id(self, url: str): 167 | endpoint = "/api/v1/tiktok/web/get_unique_id" 168 | data = await self.client.fetch_get_json(f"{endpoint}?url={url}") 169 | return data 170 | 171 | # 提取列表unique_id列表 | Get list unique_id 172 | async def get_all_unique_id(self, url: list): 173 | endpoint = "/api/v1/tiktok/web/get_all_unique_id" 174 | data = await self.client.fetch_post_json(endpoint, data={"url": url}) 175 | return data 176 | 177 | # 根据直播间链接提取直播间ID | Extract live room ID based on live room link 178 | async def get_live_room_id(self, live_room_url: str): 179 | endpoint = "/api/v1/tiktok/web/get_live_room_id" 180 | data = await self.client.fetch_get_json(f"{endpoint}?live_room_url={live_room_url}") 181 | return data 182 | 183 | # 提取直播间弹幕 - HTTP | Extract live room barrage - HTTP 184 | async def tiktok_live_room(self, live_room_url: str, danmaku_type: str): 185 | endpoint = "/api/v1/tiktok/web/tiktok_live_room" 186 | data = await self.client.fetch_get_json(f"{endpoint}?live_room_url={live_room_url}&danmaku_type={danmaku_type}") 187 | return data 188 | 189 | # 提取直播间弹幕 - WebSocket | Extract live room barrage - WebSocket 190 | async def tiktok_live_room_ws(self, live_room_url: str, danmaku_type: str): 191 | """ 192 | 提取直播间弹幕 - WebSocket | Extract webcast danmaku - WebSocket 193 | :param live_room_url: 直播间链接 | Room link 194 | :param danmaku_type: 弹幕类型 | Danmaku type 195 | :return: 弹幕数据 | Danmaku data 196 | """ 197 | endpoint = await self.tiktok_live_room(live_room_url, danmaku_type) 198 | # $.data.ws_url 199 | wss_url = endpoint["data"]["ws_url"] 200 | # 连接 WebSocket 201 | try: 202 | async with websockets.connect(wss_url, ping_interval=10, ping_timeout=5) as websocket: 203 | # 持续接收消息 204 | while True: 205 | response = await websocket.recv() 206 | print(f"Received from server: {response}") 207 | 208 | # 你可以在这里处理接收到的消息 | You can process the received message here 209 | 210 | except Exception as e: 211 | print(f"Failed to connect: {e}") 212 | 213 | # 直播间开播状态检测 | Live room broadcast status detection 214 | async def fetch_check_live_alive(self, room_id: str): 215 | endpoint = "/api/v1/tiktok/web/fetch_check_live_alive" 216 | data = await self.client.fetch_get_json(f"{endpoint}?room_id={room_id}") 217 | return data 218 | 219 | # 通过直播链接获取直播间信息(离线直播间也可以获取) | Get live room information through live link (offline live room can also be obtained) 220 | async def fetch_tiktok_live_data(self, live_room_url: str): 221 | endpoint = "/api/v1/tiktok/web/fetch_tiktok_live_data" 222 | data = await self.client.fetch_get_json(f"{endpoint}?live_room_url={live_room_url}") 223 | return data 224 | 225 | # 获取直播间首页推荐列表 | Get live room home page recommendation list 226 | async def fetch_live_recommend(self, related_live_tag: str): 227 | endpoint = "/api/v1/tiktok/web/fetch_live_recommend" 228 | data = await self.client.fetch_get_json(f"{endpoint}?related_live_tag={related_live_tag}") 229 | return data 230 | 231 | 232 | if __name__ == "__main__": 233 | import asyncio 234 | 235 | 236 | async def main(): 237 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 238 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 239 | 240 | tiktok_web = TikTokWeb(client) 241 | 242 | # 获取单个作品数据 | Get single video data 243 | item_id = "6952419395722484486" 244 | data = await tiktok_web.fetch_post_detail(item_id) 245 | print(data) 246 | 247 | # 获取用户的个人信息 | Get user profile 248 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 249 | uniqueId = None 250 | data = await tiktok_web.fetch_user_profile(secUid, uniqueId) 251 | print(data) 252 | 253 | # 获取用户的作品列表 | Get user posts 254 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 255 | cursor = 0 256 | count = 30 257 | coverFormat = 1 258 | data = await tiktok_web.fetch_user_post(secUid, cursor, count, coverFormat) 259 | print(data) 260 | 261 | # 获取用户的点赞列表 | Get user likes 262 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 263 | cursor = 0 264 | count = 30 265 | coverFormat = 1 266 | data = await tiktok_web.fetch_user_like(secUid, cursor, count, coverFormat) 267 | print(data) 268 | 269 | # 获取用户的收藏列表 | Get user favorites 270 | cookie = "" 271 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 272 | cursor = 0 273 | count = 30 274 | coverFormat = 1 275 | data = await tiktok_web.fetch_user_collect(cookie, secUid, cursor, count, coverFormat) 276 | print(data) 277 | 278 | # 获取用户的播放列表 | Get user play list 279 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 280 | cursor = 0 281 | count = 30 282 | data = await tiktok_web.fetch_user_play_list(secUid, cursor, count) 283 | 284 | # 获取用户的合辑列表 | Get user mix list 285 | mixId = "6952419395722484486" 286 | cursor = 0 287 | count = 30 288 | data = await tiktok_web.fetch_user_mix(mixId, cursor, count) 289 | print(data) 290 | 291 | # 获取作品的评论列表 | Get video comments 292 | aweme_id = "6952419395722484486" 293 | cursor = 0 294 | count = 30 295 | current_region = "CN" 296 | data = await tiktok_web.fetch_post_comment(aweme_id, cursor, count, current_region) 297 | print(data) 298 | 299 | # 获取作品的评论回复列表 | Get video comment replies 300 | item_id = "6952419395722484486" 301 | comment_id = "6952419395722484486" 302 | cursor = 0 303 | count = 30 304 | current_region = "CN" 305 | data = await tiktok_web.fetch_post_comment_reply(item_id, comment_id, cursor, count, current_region) 306 | print(data) 307 | 308 | # 获取用户的粉丝列表 | Get user followers 309 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 310 | count = 30 311 | maxCursor = 0 312 | minCursor = 0 313 | data = await tiktok_web.fetch_user_fans(secUid, count, maxCursor, minCursor) 314 | print(data) 315 | 316 | # 获取用户的关注列表 | Get user followings 317 | secUid = "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" 318 | count = 30 319 | maxCursor = 0 320 | minCursor = 0 321 | data = await tiktok_web.fetch_user_follow(secUid, count, maxCursor, minCursor) 322 | print(data) 323 | 324 | # 获取综合搜索列表 | Get general search list 325 | keyword = "tiktok" 326 | count = 30 327 | offset = 0 328 | data = await tiktok_web.fetch_general_search(keyword, count, offset) 329 | print(data) 330 | 331 | # 搜索关键字推荐 | Search keyword suggest 332 | keyword = "tiktok" 333 | data = await tiktok_web.fetch_search_keyword_suggest(keyword) 334 | print(data) 335 | 336 | # 搜索用户 | Search user 337 | keyword = "tiktok" 338 | cursor = 0 339 | data = await tiktok_web.fetch_search_user(keyword, cursor) 340 | print(data) 341 | 342 | # 搜索视频 | Search video 343 | keyword = "tiktok" 344 | count = 30 345 | offset = 0 346 | data = await tiktok_web.fetch_search_video(keyword, count, offset) 347 | print(data) 348 | 349 | # 搜索直播 | Search live 350 | keyword = "tiktok" 351 | count = 30 352 | offset = 0 353 | data = await tiktok_web.fetch_search_live(keyword, count, offset) 354 | print(data) 355 | 356 | # 生成真实msToken | Generate real msToken 357 | data = await tiktok_web.fetch_real_msToken() 358 | print(data) 359 | 360 | # 生成ttwid | Generate ttwid 361 | cookie = "" 362 | data = await tiktok_web.fetch_ttwid(cookie) 363 | print(data) 364 | 365 | # 生成xbogus | Generate xbogus 366 | url = "" 367 | user_agent = "" 368 | data = await tiktok_web.gen_xbogus(url, user_agent) 369 | print(data) 370 | 371 | # 提取用户sec_user_id | Extract user sec_user_id 372 | url = "" 373 | data = await tiktok_web.get_sec_user_id(url) 374 | print(data) 375 | 376 | # 提取列表用户sec_user_id | Extract list user sec_user_id 377 | url = [] 378 | data = await tiktok_web.get_all_sec_user_id(url) 379 | print(data) 380 | 381 | # 提取单个作品id | Extract single video id 382 | url = "" 383 | data = await tiktok_web.get_aweme_id(url) 384 | print(data) 385 | 386 | # 提取列表作品id | Extract list video id 387 | url = [] 388 | data = await tiktok_web.get_all_aweme_id(url) 389 | print(data) 390 | 391 | # 获取用户unique_id | Get user unique_id 392 | url = "" 393 | data = await tiktok_web.get_unique_id(url) 394 | print(data) 395 | 396 | # 提取列表unique_id列表 | Get list unique_id 397 | url = [] 398 | data = await tiktok_web.get_all_unique_id(url) 399 | print(data) 400 | 401 | 402 | 403 | 404 | 405 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/twitter/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/twitter/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/twitter/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/twitter/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/twitter/web/twitter_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class TwitterWeb: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # Fetch tweet detail | 获取推文详情 14 | async def fetch_tweet_detail(self, tweet_id: str): 15 | endpoint = "/api/v1/twitter/web/fetch_tweet_detail" 16 | data = await self.client.fetch_get_json(f"{endpoint}?tweet_id={tweet_id}") 17 | return data 18 | 19 | # Fetch user profile | 获取用户资料 20 | async def fetch_user_profile(self, screen_name: str = None, rest_id: int = None): 21 | endpoint = "/api/v1/twitter/web/fetch_user_profile" 22 | params = [] 23 | if screen_name: 24 | params.append(f"screen_name={screen_name}") 25 | if rest_id: 26 | params.append(f"rest_id={rest_id}") 27 | query = "&".join(params) 28 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 29 | return data 30 | 31 | # Fetch user post tweet | 获取用户发帖 32 | async def fetch_user_post_tweet(self, screen_name: str = None, rest_id: int = None, cursor: str = None): 33 | endpoint = "/api/v1/twitter/web/fetch_user_post_tweet" 34 | params = [] 35 | if screen_name: 36 | params.append(f"screen_name={screen_name}") 37 | if rest_id: 38 | params.append(f"rest_id={rest_id}") 39 | if cursor: 40 | params.append(f"cursor={cursor}") 41 | query = "&".join(params) 42 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 43 | return data 44 | 45 | # Fetch search timeline | 搜索 46 | async def fetch_search_timeline(self, keyword: str, search_type: str = "Top", cursor: str = None): 47 | endpoint = "/api/v1/twitter/web/fetch_search_timeline" 48 | params = [f"keyword={keyword}", f"search_type={search_type}"] 49 | if cursor: 50 | params.append(f"cursor={cursor}") 51 | query = "&".join(params) 52 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 53 | return data 54 | 55 | # Fetch post comments | 获取评论 56 | async def fetch_post_comments(self, tweet_id: str, cursor: str = None): 57 | endpoint = "/api/v1/twitter/web/fetch_post_comments" 58 | params = [f"tweet_id={tweet_id}"] 59 | if cursor: 60 | params.append(f"cursor={cursor}") 61 | query = "&".join(params) 62 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 63 | return data 64 | 65 | # Fetch latest post comments | 获取最新的推文评论 66 | async def fetch_latest_post_comments(self, tweet_id: str, cursor: str = None): 67 | endpoint = "/api/v1/twitter/web/fetch_latest_post_comments" 68 | params = [f"tweet_id={tweet_id}"] 69 | if cursor: 70 | params.append(f"cursor={cursor}") 71 | query = "&".join(params) 72 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 73 | return data 74 | 75 | # Fetch user tweet replies | 获取用户推文回复 76 | async def fetch_user_tweet_replies(self, screen_name: str, cursor: str = None): 77 | endpoint = "/api/v1/twitter/web/fetch_user_tweet_replies" 78 | params = [f"screen_name={screen_name}"] 79 | if cursor: 80 | params.append(f"cursor={cursor}") 81 | query = "&".join(params) 82 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 83 | return data 84 | 85 | # Fetch user highlights tweets | 获取用户高光推文 86 | async def fetch_user_highlights_tweets(self, user_id: str, count: int = 20, cursor: str = None): 87 | endpoint = "/api/v1/twitter/web/fetch_user_highlights_tweets" 88 | params = [f"userId={user_id}", f"count={count}"] 89 | if cursor: 90 | params.append(f"cursor={cursor}") 91 | query = "&".join(params) 92 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 93 | return data 94 | 95 | # Fetch user media | 获取用户媒体 96 | async def fetch_user_media(self, screen_name: str = None, rest_id: int = None): 97 | endpoint = "/api/v1/twitter/web/fetch_user_media" 98 | params = [] 99 | if screen_name: 100 | params.append(f"screen_name={screen_name}") 101 | if rest_id: 102 | params.append(f"rest_id={rest_id}") 103 | query = "&".join(params) 104 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 105 | return data 106 | 107 | # Fetch retweet user list | 转推用户列表 108 | async def fetch_retweet_user_list(self, tweet_id: str, cursor: str = None): 109 | endpoint = "/api/v1/twitter/web/fetch_retweet_user_list" 110 | params = [f"tweet_id={tweet_id}"] 111 | if cursor: 112 | params.append(f"cursor={cursor}") 113 | query = "&".join(params) 114 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 115 | return data 116 | 117 | # Fetch trending | 趋势 118 | async def fetch_trending(self, country: str = "UnitedStates"): 119 | endpoint = "/api/v1/twitter/web/fetch_trending" 120 | data = await self.client.fetch_get_json(f"{endpoint}?country={country}") 121 | return data 122 | 123 | # Fetch user followings | 用户关注 124 | async def fetch_user_followings(self, screen_name: str, cursor: str = None): 125 | endpoint = "/api/v1/twitter/web/fetch_user_followings" 126 | params = [f"screen_name={screen_name}"] 127 | if cursor: 128 | params.append(f"cursor={cursor}") 129 | query = "&".join(params) 130 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 131 | return data 132 | 133 | # Fetch user followers | 用户粉丝 134 | async def fetch_user_followers(self, screen_name: str, cursor: str = None): 135 | endpoint = "/api/v1/twitter/web/fetch_user_followers" 136 | params = [f"screen_name={screen_name}"] 137 | if cursor: 138 | params.append(f"cursor={cursor}") 139 | query = "&".join(params) 140 | data = await self.client.fetch_get_json(f"{endpoint}?{query}") 141 | return data 142 | 143 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/weibo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/weibo/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/weibo/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/weibo/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/weibo/web/weibo_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class WeiboWeb: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 获取单个作品数据 | Get single video data 14 | async def fetch_post_detail(self, id: str): 15 | endpoint = "/api/v1/weibo/web/fetch_post_detail" 16 | data = await self.client.fetch_get_json(f"{endpoint}?id={id}") 17 | return data 18 | 19 | # 获取用户信息 | Get user information 20 | async def fetch_user_info(self, uid: str): 21 | endpoint = "/api/v1/weibo/web/fetch_user_info" 22 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}") 23 | return data 24 | 25 | # 获取微博用户文章数据 | Get Weibo user article data 26 | async def fetch_user_posts(self, uid: str, page: int, feature: int): 27 | endpoint = "/api/v1/weibo/web/fetch_user_posts" 28 | data = await self.client.fetch_get_json(f"{endpoint}?uid={uid}&page={page}&feature={feature}") 29 | return data 30 | 31 | 32 | if __name__ == "__main__": 33 | import asyncio 34 | 35 | 36 | async def main(): 37 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 38 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 39 | 40 | weibo_web = WeiboWeb(client) 41 | 42 | # 获取单个作品数据 | Get single video data 43 | data = await weibo_web.fetch_post_detail("5008127060086127") 44 | print(data) 45 | 46 | # 获取用户信息 | Get user information 47 | data = await weibo_web.fetch_user_info("7277477906") 48 | print(data) 49 | 50 | # 获取微博用户文章数据 | Get Weibo user article data 51 | data = await weibo_web.fetch_user_posts("7277477906", 1, 0) 52 | print(data) 53 | 54 | 55 | asyncio.run(main()) 56 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xiaohongshu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/xiaohongshu/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xiaohongshu/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/xiaohongshu/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xiaohongshu/web/xiaohongshu_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class XiaohongshuWeb: 8 | def __init__(self, client: APIClient): 9 | self.client = client 10 | 11 | # 获取笔记信息 12 | async def get_note_info(self, note_id: str): 13 | endpoint = "/api/v1/xiaohongshu/web/get_note_info" 14 | data = await self.client.fetch_get_json(f"{endpoint}?note_id={note_id}") 15 | return data 16 | 17 | # 获取笔记信息 V2 18 | async def get_note_info_v2(self, note_id: str): 19 | endpoint = "/api/v1/xiaohongshu/web/get_note_info_v2" 20 | data = await self.client.fetch_get_json(f"{endpoint}?note_id={note_id}") 21 | return data 22 | 23 | # 获取用户信息 24 | async def get_user_info(self, user_id: str): 25 | endpoint = "/api/v1/xiaohongshu/web/get_user_info" 26 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 27 | return data 28 | 29 | # 搜索笔记 30 | async def search_notes(self, keyword: str, page: int = 1, sort: str = "general", noteType: str = "_0"): 31 | endpoint = "/api/v1/xiaohongshu/web/search_notes" 32 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&page={page}&sort={sort}¬eType={noteType}") 33 | return data 34 | 35 | # 获取用户的笔记 36 | async def get_user_notes(self, user_id: str, lastCursor: str = None): 37 | endpoint = "/api/v1/xiaohongshu/web/get_user_notes" 38 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&lastCursor={lastCursor}") 39 | return data 40 | 41 | # 获取笔记评论 42 | async def get_note_comments(self, note_id: str, lastCursor: str = None): 43 | endpoint = "/api/v1/xiaohongshu/web/get_note_comments" 44 | data = await self.client.fetch_get_json(f"{endpoint}?note_id={note_id}&lastCursor={lastCursor}") 45 | return data 46 | 47 | # 获取笔记评论回复 48 | async def get_note_comment_replies(self, note_id: str, comment_id: str, lastCursor: str = None): 49 | endpoint = "/api/v1/xiaohongshu/web/get_note_comment_replies" 50 | data = await self.client.fetch_get_json(f"{endpoint}?note_id={note_id}&comment_id={comment_id}&lastCursor={lastCursor}") 51 | return data 52 | 53 | # 搜索用户 54 | async def search_users(self, keyword: str, page: int = 1): 55 | endpoint = "/api/v1/xiaohongshu/web/search_users" 56 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&page={page}") 57 | return data 58 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xigua/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/xigua/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xigua/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/xigua/app/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/xigua/app/xigua_app_v2.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | 3 | from tikhub.http_client.api_client import APIClient 4 | 5 | # 标记已废弃的方法 6 | from tikhub.http_client.deprecated import deprecated 7 | 8 | 9 | class XiguaAppV2: 10 | 11 | # 初始化 | Initialize 12 | def __init__(self, client: APIClient): 13 | self.client = client 14 | 15 | # 获取单个作品数据 | Get single video data 16 | async def fetch_one_video(self, item_id: str): 17 | endpoint = f"/api/v1/xigua/app/v2/fetch_one_video" 18 | data = await self.client.fetch_get_json(f"{endpoint}?item_id={item_id}") 19 | return data 20 | 21 | # 视频评论列表 | Video comment list 22 | async def fetch_video_comment_list(self, item_id: str, offset: int = 0, count: int = 20): 23 | endpoint = f"/api/v1/xigua/app/v2/fetch_video_comment_list" 24 | data = await self.client.fetch_get_json(f"{endpoint}?item_id={item_id}&offset={offset}&count={count}") 25 | return data 26 | 27 | # 搜索视频 | Search video 28 | async def search_video(self, keyword: str, offset: int = 0, order_type: str = None, min_duration: int = None, max_duration: int = None): 29 | endpoint = f"/api/v1/xigua/app/v2/search_video" 30 | data = await self.client.fetch_get_json(f"{endpoint}?keyword={keyword}&offset={offset}&order_type={order_type}&min_duration={min_duration}&max_duration={max_duration}") 31 | return data 32 | 33 | # 个人信息 | Personal information 34 | async def fetch_user_info(self, user_id: str): 35 | endpoint = f"/api/v1/xigua/app/v2/fetch_user_info" 36 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}") 37 | return data 38 | 39 | # 获取个人作品列表 | Get user post list 40 | async def fetch_user_post_list(self, user_id: str, max_behot_time: str = None): 41 | endpoint = f"/api/v1/xigua/app/v2/fetch_user_post_list" 42 | data = await self.client.fetch_get_json(f"{endpoint}?user_id={user_id}&max_behot_time={max_behot_time}") 43 | return data 44 | 45 | 46 | if __name__ == "__main__": 47 | import asyncio 48 | 49 | 50 | async def main(): 51 | client = APIClient(base_url="http://127.0.0.1:8000", client_headers={ 52 | "Authorization": "Bearer l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw=="}) 53 | 54 | xigua_app_v2 = XiguaAppV2(client) 55 | 56 | asyncio.run(main()) 57 | -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/youtube/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/youtube/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/youtube/web/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/endpoints/youtube/web/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/endpoints/youtube/web/youtube_web.py: -------------------------------------------------------------------------------- 1 | # 导入API SDK Client类 2 | import json 3 | 4 | from tikhub.http_client.api_client import APIClient 5 | 6 | 7 | class YouTubeWeb: 8 | 9 | # 初始化 | Initialize 10 | def __init__(self, client: APIClient): 11 | self.client = client 12 | 13 | # 获取视频信息 | Get video information 14 | async def get_video_info(self, id: str): 15 | endpoint = "/api/v1/youtube/web/get_video_info" 16 | data = await self.client.fetch_get_json(f"{endpoint}?id={id}") 17 | return data 18 | 19 | # 获取视频字幕 | Get video subtitles 20 | async def get_video_subtitles(self, id: str, format: str = "json3"): 21 | endpoint = "/api/v1/youtube/web/get_video_subtitles" 22 | data = await self.client.fetch_get_json(f"{endpoint}?id={id}&format={format}") 23 | return data 24 | 25 | # 获取视频评论 | Get video comments 26 | async def get_video_comments(self, id: str, continuation: str = None, sort_by: str = None): 27 | endpoint = "/api/v1/youtube/web/get_video_comments" 28 | data = await self.client.fetch_get_json(f"{endpoint}?id={id}&continuation={continuation}&sort_by={sort_by}") 29 | return data 30 | 31 | # 获取短视频信息 | Get short video information 32 | async def get_short_video_info(self, id: str): 33 | endpoint = "/api/v1/youtube/web/get_short_video_info" 34 | data = await self.client.fetch_get_json(f"{endpoint}?id={id}") 35 | return data 36 | 37 | -------------------------------------------------------------------------------- /tikhub/api/v1/models/APIResponseModel.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | from typing import Any, Optional 3 | 4 | from fastapi import FastAPI 5 | from pydantic import BaseModel, Field 6 | 7 | app = FastAPI() 8 | 9 | 10 | # 定义基础响应模型 11 | class ResponseModel(BaseModel): 12 | code: int = Field(default=200, description="HTTP status code | HTTP状态码") 13 | router: str = Field(default="", description="The endpoint that generated this response | 生成此响应的端点") 14 | params: Any = Field(default={}, description="The parameters used in the request | 请求中使用的参数") 15 | data: Optional[Any] = Field(default=None, description="The response data | 响应数据") 16 | 17 | 18 | # 定义错误响应模型 19 | class ErrorResponseModel(BaseModel): 20 | code: int = Field(default=400, description="HTTP status code/HTTP状态码") 21 | message: str = Field( 22 | default="An error occurred, your account will not be charged for this request due to the error. | 服务器发生错误,您的帐户不会因此请求而被收费。", 23 | description="Error message | 错误消息") 24 | support: str = Field( 25 | default="Please contact us on Discord: https://discord.gg/aMEAS8Xsvz | 请在Discord上联系我们:https://discord.gg/aMEAS8Xsvz", 26 | description="Support message | 支持消息") 27 | time: str = Field(default=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 28 | description="The time the error occurred | 发生错误的时间") 29 | router: str = Field(default="", description="The endpoint that generated this response | 生成此响应的端点") 30 | params: dict = Field(default={}, description="The parameters used in the request | 请求中使用的参数") 31 | 32 | 33 | # 定义会话数据模型 34 | class SessionData(BaseModel): 35 | session_name: str 36 | scopes: list 37 | created_at: datetime.datetime 38 | expires_at: Optional[datetime.datetime] 39 | status: int 40 | 41 | 42 | # 定义用户数据模型 43 | class UserData(BaseModel): 44 | email: str 45 | balance: float 46 | free_credit: float 47 | email_verified: bool 48 | account_disabled: bool 49 | is_active: bool 50 | 51 | 52 | # 定义用户信息响应模型 53 | class UserInfoResponseModel(BaseModel): 54 | code: int = Field(default=200, description="HTTP status code | HTTP状态码") 55 | router: str = Field(default="", description="The endpoint that generated this response | 生成此响应的端点") 56 | session_data: SessionData 57 | user_data: UserData 58 | 59 | 60 | if __name__ == "__main__": 61 | import uvicorn 62 | 63 | uvicorn.run(app, host="127.0.0.1", port=8000) 64 | -------------------------------------------------------------------------------- /tikhub/api/v1/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/api/v1/models/__init__.py -------------------------------------------------------------------------------- /tikhub/api/v1/models/douyin_web_models.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from typing import List 3 | 4 | 5 | # 列表作品 6 | class URL_List(BaseModel): 7 | urls: List[str] = [ 8 | "https://test.example.com/xxxxx/", 9 | "https://test.example.com/yyyyy/", 10 | "https://test.example.com/zzzzz/" 11 | ] 12 | 13 | 14 | # abogus API响应模型 15 | class A_Bogus_Parameters(BaseModel): 16 | url: str = Field("https://www.douyin.com/aweme/v1/web/general/search/single/?device_platform=webapp&aid=6383&channel=channel_pc_web&search_channel=aweme_general&enable_history=1&keyword=%E4%B8%AD%E5%8D%8E%E5%A8%98&search_source=normal_search&query_correct_type=1&is_filter_search=0&from_group_id=7346905902554844468&offset=0&count=15&need_filter_settings=1&pc_client_type=1&version_code=190600&version_name=19.6.0&cookie_enabled=true&screen_width=1280&screen_height=800&browser_language=zh-CN&browser_platform=Win32&browser_name=Firefox&browser_version=124.0&browser_online=true&engine_name=Gecko&engine_version=124.0&os_name=Windows&os_version=10&cpu_core_num=16&device_memory=&platform=PC&webid=7348962975497324070&msToken=YCTVM6YGmjFdIpQAN9ykXLBXiSiuHdZkOkEQWTeqVOHBEPmOcM0lNwE0Kd9vgHPMPigSndZDHfAq9k-6lDmH3Jqz6mHHxmn-BzQjmLMIfLIPgirgnOixM9x4PwgcNQ%3D%3D", 17 | description='url,需要使用urlencode(data, safe="*")进行编码') 18 | 19 | data: str = Field("", description='body,需要使用urlencode(data, safe="*")进行编码') 20 | 21 | user_agent: str = Field( 22 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36", 23 | description='user-agent') 24 | index_0: int = Field(0, description='加密明文列表的第一个值,无特殊要求,默认为0') 25 | index_1: int = Field(1, description='加密明文列表的第一个值,无特殊要求,默认为1') 26 | index_2: int = Field(14, description='加密明文列表的第一个值,无特殊要求,默认为14') 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tikhub/client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/client/__init__.py -------------------------------------------------------------------------------- /tikhub/client/client.py: -------------------------------------------------------------------------------- 1 | # import SDK Version 2 | from tikhub import version 3 | 4 | # http_client 5 | from tikhub.http_client.api_client import APIClient 6 | 7 | # TikHub 8 | from tikhub.api.v1.endpoints.tikhub.tikhub_user import TikHubUser 9 | 10 | # Douyin 11 | from tikhub.api.v1.endpoints.douyin.web.douyin_web import DouyinWeb 12 | from tikhub.api.v1.endpoints.douyin.app.douyin_app_v1 import DouyinAppV1 13 | from tikhub.api.v1.endpoints.douyin.app.douyin_app_v2 import DouyinAppV2 14 | from tikhub.api.v1.endpoints.douyin.app.douyin_app_v3 import DouyinAppV3 15 | 16 | # TikTok 17 | from tikhub.api.v1.endpoints.tiktok.web.tiktok_web import TikTokWeb 18 | from tikhub.api.v1.endpoints.tiktok.app.tiktok_app_v2 import TikTokAppV2 19 | from tikhub.api.v1.endpoints.tiktok.app.tiktok_app_v3 import TikTokAppV3 20 | 21 | # Instagram 22 | from tikhub.api.v1.endpoints.instagram.web.instagram_web import InstagramWeb 23 | 24 | # Weibo 25 | from tikhub.api.v1.endpoints.weibo.web.weibo_web import WeiboWeb 26 | 27 | # Captcha Solver 28 | from tikhub.api.v1.endpoints.captcha.captcha_solver import CaptchaSolver 29 | 30 | # Xigua Video APP V2 31 | from tikhub.api.v1.endpoints.xigua.app.xigua_app_v2 import XiguaAppV2 32 | 33 | # XiaoHongShu Web 34 | from tikhub.api.v1.endpoints.xiaohongshu.web.xiaohongshu_web import XiaohongshuWeb 35 | 36 | # KuaiShou Web 37 | from tikhub.api.v1.endpoints.kuaishou.web.kuaishou_web import KuaishouWeb 38 | 39 | # YouTube Web 40 | from tikhub.api.v1.endpoints.youtube.web.youtube_web import YouTubeWeb 41 | 42 | # Net Ease Cloud Music 43 | from tikhub.api.v1.endpoints.net_ease_cloud_music.app.net_ease_cloud_music_app_v1 import NetEaseCloudMusicAppV1 44 | 45 | # Hybrid Parsing 46 | from tikhub.api.v1.endpoints.hybrid_parsing.hybrid_parsing import HybridParsing 47 | 48 | # Twitter Web 49 | from tikhub.api.v1.endpoints.twitter.web.twitter_web import TwitterWeb 50 | 51 | 52 | class Client: 53 | def __init__(self, 54 | base_url: str = 'https://api.tikhub.io', 55 | api_key: str = None, 56 | proxies: dict = None, 57 | max_retries: int = 3, 58 | max_connections: int = 50, 59 | timeout: int = 60, 60 | max_tasks: int = 50, 61 | custom_user_agent: str = None, 62 | ): 63 | # Base URL 64 | self.base_url = base_url 65 | 66 | # API Key 67 | self.api_key = api_key 68 | if not self.api_key: 69 | raise RuntimeError("API Key is required to use the SDK. | 需要API Key才能使用SDK。") 70 | 71 | # Version 72 | self.version = str(version) 73 | 74 | # API Client 75 | self.client = APIClient( 76 | base_url=self.base_url, 77 | client_headers={ 78 | "User-Agent": f"TikHub-API-SDK-Python/{self.version}" if not custom_user_agent else custom_user_agent, 79 | "X-SDK-Version": f"{self.version}", 80 | "Authorization": f"Bearer {self.api_key}" 81 | }, 82 | proxies=proxies, 83 | max_retries=max_retries, 84 | max_connections=max_connections, 85 | timeout=timeout, 86 | max_tasks=max_tasks 87 | ) 88 | 89 | # TikHub 90 | self.TikHubUser = TikHubUser(self.client) 91 | 92 | # Douyin 93 | self.DouyinWeb = DouyinWeb(self.client) 94 | self.DouyinAppV1 = DouyinAppV1(self.client) 95 | self.DouyinAppV2 = DouyinAppV2(self.client) 96 | self.DouyinAppV3 = DouyinAppV3(self.client) 97 | 98 | # TikTok 99 | self.TikTokWeb = TikTokWeb(self.client) 100 | self.TikTokAppV2 = TikTokAppV2(self.client) 101 | self.TikTokAppV3 = TikTokAppV3(self.client) 102 | 103 | # Instagram 104 | self.InstagramWeb = InstagramWeb(self.client) 105 | 106 | # Weibo 107 | self.WeiboWeb = WeiboWeb(self.client) 108 | 109 | # Captcha Solver 110 | self.CaptchaSolver = CaptchaSolver(self.client) 111 | 112 | # Xigua Video APP V2 113 | self.XiguaAppV2 = XiguaAppV2(self.client) 114 | 115 | # XiaoHongShu Web 116 | self.XiaohongshuWeb = XiaohongshuWeb(self.client) 117 | 118 | # KuaiShou Web 119 | self.KuaishouWeb = KuaishouWeb(self.client) 120 | 121 | # YouTube Web 122 | self.YouTubeWeb = YouTubeWeb(self.client) 123 | 124 | # Net Ease Cloud Music 125 | self.NetEaseCloudMusicAppV1 = NetEaseCloudMusicAppV1(self.client) 126 | 127 | # Twitter Web 128 | self.TwitterWeb = TwitterWeb(self.client) 129 | 130 | # Hybrid Parsing 131 | self.HybridParsing = HybridParsing(self.client) 132 | 133 | """ 134 | [中文] 135 | 136 | 这些代码用于实现异步上下文管理器,使得类的实例可以与 async with 语句一起使用,从而在进入和退出时自动处理资源的初始化和清理。 137 | 138 | 例如: 139 | async with Client(api_key=api_key) as client: 140 | pass 141 | 142 | 这样在退出时会自动调用 __aexit__ 方法,关闭 client。 143 | 144 | [English] 145 | 146 | This code is used to implement an asynchronous context manager, 147 | which allows instances of a class to be used with the async with statement, 148 | automatically handling the initialization and cleanup of resources when entering and exiting. 149 | 150 | For example: 151 | async with Client(api_key=api_key) as client: 152 | pass 153 | 154 | This way, the __aexit__ method is automatically called when exiting, closing the client. 155 | """ 156 | 157 | async def __aenter__(self): 158 | return self 159 | 160 | async def __aexit__(self, exc_type, exc_val, exc_tb): 161 | await self.client.close() 162 | 163 | 164 | if __name__ == '__main__': 165 | # Example 166 | api_key = "YOUR_API_KEY" 167 | client = Client(api_key=api_key) 168 | -------------------------------------------------------------------------------- /tikhub/http_client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/http_client/__init__.py -------------------------------------------------------------------------------- /tikhub/http_client/api_client.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from typing import Union, List, Any 3 | 4 | import httpx 5 | from httpx import Response 6 | 7 | from tikhub.http_client.api_exceptions import ( 8 | APIError, 9 | APIConnectionError, 10 | APIResponseError, 11 | APITimeoutError, 12 | APIUnavailableError, 13 | APIUnauthorizedError, 14 | APINotFoundError, 15 | APIRateLimitError, 16 | APIRetryExhaustedError, 17 | ) 18 | from tikhub.http_client.api_logger import logger 19 | 20 | 21 | class APIClient: 22 | """ 23 | 基础API客户端 (Base API http_client) 24 | """ 25 | 26 | def __init__( 27 | self, 28 | base_url: str, 29 | client_headers: dict, 30 | proxies: dict = None, 31 | max_retries: int = 3, 32 | max_connections: int = 50, 33 | timeout: int = 30, 34 | max_tasks: int = 50, 35 | ): 36 | if isinstance(proxies, dict): 37 | self.proxies = proxies 38 | # [f"{k}://{v}" for k, v in proxies.items()] 39 | else: 40 | self.proxies = None 41 | 42 | # API基础URL / API base URL 43 | self.base_url = base_url 44 | # API请求头 / API request header 45 | self.client_headers = client_headers 46 | 47 | # 异步的任务数 / Number of asynchronous tasks 48 | self._max_tasks = max_tasks 49 | self.semaphore = asyncio.Semaphore(max_tasks) 50 | 51 | # 限制最大连接数 / Limit the maximum number of connections 52 | self._max_connections = max_connections 53 | self.limits = httpx.Limits(max_connections=max_connections) 54 | 55 | # 业务逻辑重试次数 / Business logic retry count 56 | self._max_retries = max_retries 57 | # 底层连接重试次数 / Underlying connection retry count 58 | self.atransport = httpx.AsyncHTTPTransport(retries=max_retries) 59 | 60 | # 超时等待时间 / Timeout waiting time 61 | self._timeout = timeout 62 | self.timeout = httpx.Timeout(timeout) 63 | # 异步客户端 / Asynchronous http_client 64 | self.aclient = httpx.AsyncClient( 65 | headers=self.client_headers, 66 | proxies=self.proxies, 67 | timeout=self.timeout, 68 | limits=self.limits, 69 | transport=self.atransport, 70 | ) 71 | 72 | async def fetch_response(self, endpoint: str) -> Response: 73 | """获取数据 (Get data) 74 | 75 | Args: 76 | endpoint (str): 接口地址 (Endpoint URL) 77 | 78 | Returns: 79 | Response: 原始响应对象 (Raw response object) 80 | """ 81 | return await self.get_fetch_data(f"{self.base_url}{endpoint}") 82 | 83 | async def fetch_get_json(self, endpoint: str) -> Union[dict, List[Any]]: 84 | """获取 JSON 数据 (Get JSON data) 85 | 86 | Args: 87 | endpoint (str): 接口地址 (Endpoint URL) 88 | 89 | Returns: 90 | dict: 解析后的JSON数据 (Parsed JSON data) 91 | """ 92 | response = await self.get_fetch_data(f"{self.base_url}{endpoint}") 93 | return self.parse_json(response) 94 | 95 | async def fetch_post_json(self, endpoint: str, params: dict = {}, data=None) -> Union[dict, List[Any]]: 96 | """获取 JSON 数据 (Post JSON data) 97 | 98 | Args: 99 | endpoint (str): 接口地址 (Endpoint URL) 100 | 101 | Returns: 102 | dict: 解析后的JSON数据 (Parsed JSON data) 103 | """ 104 | response = await self.post_fetch_data(f"{self.base_url}{endpoint}", params, data) 105 | return self.parse_json(response) 106 | 107 | def parse_json(self, response: Response) -> Union[dict, List[Any]]: 108 | """解析 JSON 数据 (Parse JSON data)""" 109 | 110 | return response.json() 111 | 112 | async def get_fetch_data(self, url: str): 113 | """ 114 | 获取GET端点数据 (Get GET endpoint data) 115 | 116 | Args: 117 | url (str): 端点URL (Endpoint URL) 118 | 119 | Returns: 120 | response: 响应内容 (Response content) 121 | """ 122 | for attempt in range(self._max_retries): 123 | try: 124 | response = await self.aclient.get(url, follow_redirects=True) 125 | if not response.text.strip() or not response.content: 126 | error_message = "第 {0} 次响应内容为空, 状态码: {1}, URL:{2}".format(attempt + 1, 127 | response.status_code, 128 | response.url) 129 | 130 | logger.warning(error_message) 131 | 132 | if attempt == self._max_retries - 1: 133 | raise APIRetryExhaustedError( 134 | "获取端点数据失败, 次数达到上限" 135 | ) 136 | 137 | await asyncio.sleep(self._timeout) 138 | continue 139 | 140 | # logger.info("响应状态码: {0}".format(response.status_code)) 141 | response.raise_for_status() 142 | return response 143 | 144 | except httpx.RequestError: 145 | raise APIConnectionError("连接端点失败,检查网络环境或代理:{0} 代理:{1} 类名:{2}" 146 | .format(url, self.proxies, self.__class__.__name__) 147 | ) 148 | 149 | except httpx.HTTPStatusError as http_error: 150 | self.handle_http_status_error(http_error, url, attempt + 1) 151 | 152 | except APIError as e: 153 | e.display_error() 154 | 155 | async def post_fetch_data(self, url: str, params: dict = {}, data=None): 156 | """ 157 | 获取POST端点数据 (Get POST endpoint data) 158 | 159 | Args: 160 | url (str): 端点URL (Endpoint URL) 161 | params (dict): POST请求参数 (POST request parameters) 162 | 163 | Returns: 164 | response: 响应内容 (Response content) 165 | """ 166 | for attempt in range(self._max_retries): 167 | try: 168 | response = await self.aclient.post( 169 | url, 170 | json=None if not params else dict(params), 171 | data=None if not data else data, 172 | follow_redirects=True 173 | ) 174 | if not response.text.strip() or not response.content: 175 | error_message = "第 {0} 次响应内容为空, 状态码: {1}, URL:{2}".format(attempt + 1, 176 | response.status_code, 177 | response.url) 178 | 179 | logger.warning(error_message) 180 | 181 | if attempt == self._max_retries - 1: 182 | raise APIRetryExhaustedError( 183 | "获取端点数据失败, 次数达到上限" 184 | ) 185 | 186 | await asyncio.sleep(self._timeout) 187 | continue 188 | 189 | # logger.info("响应状态码: {0}".format(response.status_code)) 190 | response.raise_for_status() 191 | return response 192 | 193 | except httpx.RequestError: 194 | raise APIConnectionError( 195 | "连接端点失败,检查网络环境或代理:{0} 代理:{1} 类名:{2}".format(url, self.proxies, 196 | self.__class__.__name__) 197 | ) 198 | 199 | except httpx.HTTPStatusError as http_error: 200 | self.handle_http_status_error(http_error, url, attempt + 1) 201 | 202 | except APIError as e: 203 | e.display_error() 204 | 205 | async def head_fetch_data(self, url: str): 206 | """ 207 | 获取HEAD端点数据 (Get HEAD endpoint data) 208 | 209 | Args: 210 | url (str): 端点URL (Endpoint URL) 211 | 212 | Returns: 213 | response: 响应内容 (Response content) 214 | """ 215 | try: 216 | response = await self.aclient.head(url) 217 | # logger.info("响应状态码: {0}".format(response.status_code)) 218 | response.raise_for_status() 219 | return response 220 | 221 | except httpx.RequestError: 222 | raise APIConnectionError("连接端点失败,检查网络环境或代理:{0} 代理:{1} 类名:{2}".format( 223 | url, self.proxies, self.__class__.__name__ 224 | ) 225 | ) 226 | 227 | except httpx.HTTPStatusError as http_error: 228 | self.handle_http_status_error(http_error, url, 1) 229 | 230 | except APIError as e: 231 | e.display_error() 232 | 233 | def handle_http_status_error(self, http_error, url: str, attempt): 234 | """ 235 | 处理HTTP状态错误 (Handle HTTP status error) 236 | 237 | Args: 238 | http_error: HTTP状态错误 (HTTP status error) 239 | url: 端点URL (Endpoint URL) 240 | attempt: 尝试次数 (Number of attempts) 241 | Raises: 242 | APIConnectionError: 连接端点失败 (Failed to connect to endpoint) 243 | APIResponseError: 响应错误 (Response error) 244 | APIUnavailableError: 服务不可用 (Service unavailable) 245 | APINotFoundError: 端点不存在 (Endpoint does not exist) 246 | APITimeoutError: 连接超时 (Connection timeout) 247 | APIUnauthorizedError: 未授权 (Unauthorized) 248 | APIRateLimitError: 请求频率过高 (Request frequency is too high) 249 | APIRetryExhaustedError: 重试次数达到上限 (The number of retries has reached the upper limit) 250 | """ 251 | response = getattr(http_error, "response", None) 252 | response_text = getattr(response, "text", None) 253 | status_code = getattr(response, "status_code", None) 254 | 255 | if response is None or status_code is None: 256 | logger.error("HTTP状态错误: {0}, URL: {1}, 尝试次数: {2}".format( 257 | http_error, url, attempt 258 | ) 259 | ) 260 | raise APIResponseError(f"处理HTTP错误时遇到意外情况: {http_error}") 261 | 262 | if status_code == 302: 263 | pass 264 | elif status_code == 404: 265 | raise APINotFoundError(f"HTTP Status Code {status_code}, check your URL") 266 | elif status_code == 503: 267 | raise APIUnavailableError(f"HTTP Status Code {status_code}") 268 | elif status_code == 408: 269 | raise APITimeoutError(f"HTTP Status Code {status_code}") 270 | elif status_code == 401: 271 | raise APIUnauthorizedError(f"HTTP Status Code {status_code}, check your API key") 272 | elif status_code == 429: 273 | raise APIRateLimitError(f"HTTP Status Code {status_code}") 274 | else: 275 | logger.error("HTTP状态错误: {0}, URL: {1}, 尝试次数: {2}".format( 276 | status_code, url, attempt 277 | ) 278 | ) 279 | raise APIResponseError(f"\n程序出现异常,请检查错误信息。 | An error occurred in the program, please check the error message." 280 | f"\nHTTP Status Code: {status_code}" 281 | f"\nResponse: {response_text}" 282 | f"\nURL: {url}") 283 | 284 | async def close(self): 285 | await self.aclient.aclose() 286 | 287 | async def __aenter__(self): 288 | return self 289 | 290 | async def __aexit__(self, exc_type, exc_val, exc_tb): 291 | await self.aclient.aclose() 292 | -------------------------------------------------------------------------------- /tikhub/http_client/api_exceptions.py: -------------------------------------------------------------------------------- 1 | class APIError(Exception): 2 | """ 3 | 基本API异常类,其他API异常都会继承这个类 4 | 5 | Base API exception class, all other API exceptions will inherit this class 6 | """ 7 | 8 | def __init__(self, status_code=None): 9 | self.status_code = status_code 10 | print( 11 | "程序出现异常,请检查错误信息。 | An error occurred in the program, please check the error message." 12 | ) 13 | 14 | def display_error(self): 15 | """ 16 | 显示错误信息和状态码(如果有的话) 17 | 18 | Display the error message and status code (if any) 19 | """ 20 | return f"Error: {self.args[0]}." + ( 21 | f" Status Code: {self.status_code}." if self.status_code else "" 22 | ) 23 | 24 | 25 | class APIConnectionError(APIError): 26 | """ 27 | 当与API的连接出现问题时抛出 28 | 29 | Raised when there is a problem connecting to the API 30 | """ 31 | 32 | def display_error(self): 33 | return f"API Connection Error: {self.args[0]}." 34 | 35 | 36 | class APIUnavailableError(APIError): 37 | """ 38 | 当API服务不可用时抛出,例如维护或超时 39 | 40 | Raised when the API service is unavailable, such as maintenance or timeout 41 | """ 42 | 43 | def display_error(self): 44 | return f"API Unavailable Error: {self.args[0]}." 45 | 46 | 47 | class APINotFoundError(APIError): 48 | """ 49 | 当API端点不存在时抛出 50 | 51 | Raised when the API endpoint does not exist 52 | """ 53 | 54 | def display_error(self): 55 | return f"API Not Found Error: {self.args[0]}." 56 | 57 | 58 | class APIResponseError(APIError): 59 | """ 60 | 当API返回的响应与预期不符时抛出 61 | 62 | Raised when the response returned by the API does not match the expected 63 | """ 64 | 65 | def display_error(self): 66 | return f"API Response Error: {self.args[0]}." 67 | 68 | 69 | class APIRateLimitError(APIError): 70 | """ 71 | 当达到API的请求速率限制时抛出 72 | 73 | Raised when the request rate limit of the API is reached 74 | """ 75 | 76 | def display_error(self): 77 | return f"API Rate Limit Error: {self.args[0]}." 78 | 79 | 80 | class APITimeoutError(APIError): 81 | """ 82 | 当API请求超时时抛出 83 | 84 | Raised when the API request times out 85 | """ 86 | 87 | def display_error(self): 88 | return f"API Timeout Error: {self.args[0]}." 89 | 90 | 91 | class APIUnauthorizedError(APIError): 92 | """ 93 | 当API请求由于授权失败而被拒绝时抛出 94 | 95 | Raised when an API request is denied due to authorization failure 96 | """ 97 | 98 | def display_error(self): 99 | return f"API Unauthorized Error: {self.args[0]}." 100 | 101 | 102 | class APIRetryExhaustedError(APIError): 103 | """ 104 | 当API请求重试次数用尽时抛出 105 | 106 | Raised when the API request retry count is exhausted 107 | """ 108 | 109 | def display_error(self): 110 | return f"API Retry Exhausted Error: {self.args[0]}." 111 | -------------------------------------------------------------------------------- /tikhub/http_client/api_logger.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import time 3 | import logging 4 | from rich.logging import RichHandler 5 | 6 | 7 | class Singleton(type): 8 | _instances = {} # 存储实例的字典 9 | _lock: threading.Lock = threading.Lock() # 线程锁 10 | 11 | def __init__(self, *args, **kwargs): 12 | super().__init__(*args, **kwargs) 13 | 14 | def __call__(cls, *args, **kwargs): 15 | """ 16 | 重写默认的类实例化方法。当尝试创建类的一个新实例时,此方法将被调用。 17 | 如果已经有一个与参数匹配的实例存在,则返回该实例;否则创建一个新实例。 18 | """ 19 | key = (cls, args, frozenset(kwargs.items())) 20 | with cls._lock: 21 | if key not in cls._instances: 22 | instance = super().__call__(*args, **kwargs) 23 | cls._instances[key] = instance 24 | return cls._instances[key] 25 | 26 | @classmethod 27 | def reset_instance(cls, *args, **kwargs): 28 | """ 29 | 重置指定参数的实例。这只是从 _instances 字典中删除实例的引用, 30 | 并不真正删除该实例。如果其他地方仍引用该实例,它仍然存在且可用。 31 | """ 32 | key = (cls, args, frozenset(kwargs.items())) 33 | with cls._lock: 34 | if key in cls._instances: 35 | del cls._instances[key] 36 | 37 | 38 | class LogManager(metaclass=Singleton): 39 | def __init__(self): 40 | if getattr(self, "_initialized", False): # 防止重复初始化 41 | return 42 | 43 | self.logger = logging.getLogger("TikHub_API_SDK") 44 | self.logger.setLevel(logging.INFO) 45 | self.log_dir = None 46 | self._initialized = True 47 | 48 | def setup_logging(self, level=logging.INFO, log_to_console=False): 49 | self.logger.handlers.clear() 50 | self.logger.setLevel(level) 51 | 52 | if log_to_console: 53 | ch = RichHandler( 54 | show_time=False, 55 | show_path=False, 56 | markup=True, 57 | keywords=(RichHandler.KEYWORDS or []) + ["STREAM"], 58 | rich_tracebacks=True, 59 | ) 60 | ch.setFormatter(logging.Formatter("{message}", style="{", datefmt="[%X]")) 61 | self.logger.addHandler(ch) 62 | 63 | def shutdown(self): 64 | for handler in self.logger.handlers: 65 | handler.close() 66 | self.logger.removeHandler(handler) 67 | self.logger.handlers.clear() 68 | time.sleep(1) # 确保文件被释放 69 | 70 | 71 | def log_setup(log_to_console=True): 72 | logger = logging.getLogger("TikHub_Python_SDK") 73 | if logger.hasHandlers(): 74 | # logger已经被设置,不做任何操作 75 | return logger 76 | 77 | # 创建临时的日志目录 78 | # temp_log_dir = Path("./logs") 79 | # temp_log_dir.mkdir(exist_ok=True) 80 | 81 | # 初始化日志管理器 82 | log_manager = LogManager() 83 | log_manager.setup_logging( 84 | level=logging.INFO, log_to_console=log_to_console 85 | ) 86 | 87 | return logger 88 | 89 | 90 | logger = log_setup() 91 | -------------------------------------------------------------------------------- /tikhub/http_client/deprecated.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | import functools 3 | 4 | 5 | def deprecated(message): 6 | def decorator(func): 7 | @functools.wraps(func) 8 | async def wrapper(*args, **kwargs): 9 | warnings.warn( 10 | f"{func.__name__} is deprecated: {message}", 11 | DeprecationWarning, 12 | stacklevel=2 13 | ) 14 | return await func(*args, **kwargs) 15 | 16 | return wrapper 17 | 18 | return decorator 19 | -------------------------------------------------------------------------------- /tikhub/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TikHub/TikHub-API-Python-SDK/d991d9347fd7ba1058d92b599c84612df57d50d4/tikhub/test/__init__.py -------------------------------------------------------------------------------- /tikhub/test/test.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from tikhub import Client 3 | 4 | 5 | async def main(): 6 | client = Client(base_url="https://beta.tikhub.io", api_key="l7sVQFh64V8ltC8fzEaNtWE60zVSopDLlpVX62fArT1FznsPds9+2RGoXw==") 7 | 8 | # 请求用户信息 | Request user info 9 | user_info = await client.TikHubUser.get_user_info() 10 | print(user_info) 11 | 12 | # 请求用户每日使用情况 | Request user daily usage 13 | user_daily_usage = await client.TikHubUser.get_user_daily_usage() 14 | print(user_daily_usage) 15 | 16 | # 计算价格 | Calculate price 17 | price = await client.TikHubUser.calculate_price(endpoint="/api/v1/douyin/app/v1/fetch_one_video", request_per_day=100) 18 | print(price) 19 | 20 | # 获取阶梯式折扣百分比信息 | Get tiered discount percentage information 21 | tiered_discount_info = await client.TikHubUser.get_tiered_discount_info() 22 | print(tiered_discount_info) 23 | 24 | # 获取一个端点的信息 | Get information of an endpoint 25 | endpoint_info = await client.TikHubUser.get_endpoint_info(endpoint="/api/v1/douyin/app/v1/fetch_one_video") 26 | print(endpoint_info) 27 | 28 | # 获取所有端点信息 | Get all endpoints information 29 | all_endpoints_info = await client.TikHubUser.get_all_endpoints_info() 30 | print(all_endpoints_info) 31 | 32 | 33 | asyncio.run(main()) 34 | -------------------------------------------------------------------------------- /tikhub/version.py: -------------------------------------------------------------------------------- 1 | # tikhub/version.py 2 | version = "1.12.9" 3 | --------------------------------------------------------------------------------