<p align="center">
<a href="https://github.com/Drelf2018/submitter/">
<img src="https://user-images.githubusercontent.com/41439182/220989932-10aeb2f4-9526-4ec5-9991-b5960041be1f.png" height="200" alt="submitter">
</a>
</p>
<div align="center">
# submitter
_✨ 基于 [webhook](https://github.com/Drelf2018/webhook) 的博文提交器 ✨_
</div>
<p align="center">
<a href="https://pypi.org/project/post-submitter/">下载</a>
·
<a href="https://github.com/Drelf2018/submitter/blob/main/tests/ali.py">开始使用</a>
</p>
### 教程
下面这段代码是适配的我自己在阿里云上创建的 [webhook](https://github.com/Drelf2018/webhook) 实例。这个实例是通过扫描哔哩哔哩二维码来实现账户验证的,所以我们在创建账号时要先获取B站的验证链接,生成二维码。此时程序会通过输入暂停住,用手机扫码后稍等三秒再回车就可以通过验证了。`Token` 信息也会打印在屏幕上,可以保存在代码里,这样下次登录就不用账号密码了,例如 `@AliClient(ping=30, token=token)` 就不用再提供账号密码。其中这里的 `ping=30` 含义是每 `30` 秒向服务器报告一次自己在线,这样后续在网站上就可以看到自己的提交器是否还在正常工作,但是这个不是强制的,如果你不想报告自身状态,设置 `ping=-1` 这样的负数即可。
接下来就是提交器正式工作内容了,这里从 `submitter.adapter.weibo` 导入了适配器 `Weibo`,顾名思义就是将微博博文适配成 [webhook](https://github.com/Drelf2018/webhook) 规定的博文结构的工具。它的具体使用方法还请阅读源代码,非常简单易懂,通过阅读源码你也可以学习如何编写一个别的平台的适配器。后面我们从适配器中取出了第一个收集到的博文,并且发送至服务器用以测试任务 `Task`,这是 [webhook/model/user.go](https://github.com/Drelf2018/webhook/blob/ad577b5f93a67820545b2cddc2a999c6a352dd3e/model/user.go#L40) 中定义的一种请求结构,用来实现广播博文,也就是 `webhook` 的实现。
希望这个工具对你有用!
```py
from qrcode import QRCode
from submitter import Client, Task
from submitter.adapter.weibo import Weibo
class AliClient(Client):
def __init__(self, uid: str = "", password: str = "", token: str = "", ping: float = -1):
super().__init__("http://gin.web-framework-m88s.1990019364850918.cn-hangzhou.fc.devsapp.net", uid, password, token, ping)
async def register(self) -> str:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54",
"Referer": "https://www.bilibili.com",
}
resp = await self.session.get("https://passport.bilibili.com/x/passport-login/web/qrcode/generate", headers=headers)
result = resp.json()
qr = QRCode(border=0)
qr.add_data(result["data"]["url"])
qr.make()
qr.print_ascii()
input("扫描二维码完成登录后按下回车继续注册")
data = {
"uid": self.uid,
"password": self.password,
"qrcode_key": result["data"]["qrcode_key"],
}
if await self.post("/register", json=data) == "success":
return await self.token(self.uid, self.password)
@AliClient(uid="your_bilibili_uid", password="the_account_password_you_want_to_use_to_submit_blog")
async def main(self: AliClient):
token = await self.register()
self.log.info(f"Token[{token}]")
# 注册完后就可以吧这个函数删了 用下面那个 注意用获取到的 Token 替换下面的空字符串
@AliClient(ping=30, token="")
async def ali(self: AliClient):
async with Weibo(preload=["7198559139"]) as w:
for mid in w.blogs:
log = await self.test(
blog=w.blogs[mid],
task=Task(
public=True,
enable=True,
name="接收测试",
method="POST",
url="https://httpbin.org/post",
body="{{ json . }}",
README="接收所有微博",
),
)
self.log.info(log)
break
```
Raw data
{
"_id": null,
"home_page": "https://github.com/Drelf2018/submitter",
"name": "post-submitter",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "python, weibo, webhook",
"author": "Drelf2018",
"author_email": "drelf2018@outlook.com",
"download_url": "https://files.pythonhosted.org/packages/b5/96/2f48ade2018c8ed128fdebe011996bfdb9df1cd3d76a35cb5d94b813c7a1/post-submitter-0.6.0.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <a href=\"https://github.com/Drelf2018/submitter/\">\n <img src=\"https://user-images.githubusercontent.com/41439182/220989932-10aeb2f4-9526-4ec5-9991-b5960041be1f.png\" height=\"200\" alt=\"submitter\">\n </a>\n</p>\n\n<div align=\"center\">\n\n# submitter\n\n_\u2728 \u57fa\u4e8e [webhook](https://github.com/Drelf2018/webhook) \u7684\u535a\u6587\u63d0\u4ea4\u5668 \u2728_ \n\n</div>\n\n<p align=\"center\">\n <a href=\"https://pypi.org/project/post-submitter/\">\u4e0b\u8f7d</a>\n \u00b7\n <a href=\"https://github.com/Drelf2018/submitter/blob/main/tests/ali.py\">\u5f00\u59cb\u4f7f\u7528</a>\n</p>\n\n### \u6559\u7a0b\n\n\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u662f\u9002\u914d\u7684\u6211\u81ea\u5df1\u5728\u963f\u91cc\u4e91\u4e0a\u521b\u5efa\u7684 [webhook](https://github.com/Drelf2018/webhook) \u5b9e\u4f8b\u3002\u8fd9\u4e2a\u5b9e\u4f8b\u662f\u901a\u8fc7\u626b\u63cf\u54d4\u54e9\u54d4\u54e9\u4e8c\u7ef4\u7801\u6765\u5b9e\u73b0\u8d26\u6237\u9a8c\u8bc1\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u5728\u521b\u5efa\u8d26\u53f7\u65f6\u8981\u5148\u83b7\u53d6B\u7ad9\u7684\u9a8c\u8bc1\u94fe\u63a5\uff0c\u751f\u6210\u4e8c\u7ef4\u7801\u3002\u6b64\u65f6\u7a0b\u5e8f\u4f1a\u901a\u8fc7\u8f93\u5165\u6682\u505c\u4f4f\uff0c\u7528\u624b\u673a\u626b\u7801\u540e\u7a0d\u7b49\u4e09\u79d2\u518d\u56de\u8f66\u5c31\u53ef\u4ee5\u901a\u8fc7\u9a8c\u8bc1\u4e86\u3002`Token` \u4fe1\u606f\u4e5f\u4f1a\u6253\u5370\u5728\u5c4f\u5e55\u4e0a\uff0c\u53ef\u4ee5\u4fdd\u5b58\u5728\u4ee3\u7801\u91cc\uff0c\u8fd9\u6837\u4e0b\u6b21\u767b\u5f55\u5c31\u4e0d\u7528\u8d26\u53f7\u5bc6\u7801\u4e86\uff0c\u4f8b\u5982 `@AliClient(ping=30, token=token)` \u5c31\u4e0d\u7528\u518d\u63d0\u4f9b\u8d26\u53f7\u5bc6\u7801\u3002\u5176\u4e2d\u8fd9\u91cc\u7684 `ping=30` \u542b\u4e49\u662f\u6bcf `30` \u79d2\u5411\u670d\u52a1\u5668\u62a5\u544a\u4e00\u6b21\u81ea\u5df1\u5728\u7ebf\uff0c\u8fd9\u6837\u540e\u7eed\u5728\u7f51\u7ad9\u4e0a\u5c31\u53ef\u4ee5\u770b\u5230\u81ea\u5df1\u7684\u63d0\u4ea4\u5668\u662f\u5426\u8fd8\u5728\u6b63\u5e38\u5de5\u4f5c\uff0c\u4f46\u662f\u8fd9\u4e2a\u4e0d\u662f\u5f3a\u5236\u7684\uff0c\u5982\u679c\u4f60\u4e0d\u60f3\u62a5\u544a\u81ea\u8eab\u72b6\u6001\uff0c\u8bbe\u7f6e `ping=-1` \u8fd9\u6837\u7684\u8d1f\u6570\u5373\u53ef\u3002\n\n\u63a5\u4e0b\u6765\u5c31\u662f\u63d0\u4ea4\u5668\u6b63\u5f0f\u5de5\u4f5c\u5185\u5bb9\u4e86\uff0c\u8fd9\u91cc\u4ece `submitter.adapter.weibo` \u5bfc\u5165\u4e86\u9002\u914d\u5668 `Weibo`\uff0c\u987e\u540d\u601d\u4e49\u5c31\u662f\u5c06\u5fae\u535a\u535a\u6587\u9002\u914d\u6210 [webhook](https://github.com/Drelf2018/webhook) \u89c4\u5b9a\u7684\u535a\u6587\u7ed3\u6784\u7684\u5de5\u5177\u3002\u5b83\u7684\u5177\u4f53\u4f7f\u7528\u65b9\u6cd5\u8fd8\u8bf7\u9605\u8bfb\u6e90\u4ee3\u7801\uff0c\u975e\u5e38\u7b80\u5355\u6613\u61c2\uff0c\u901a\u8fc7\u9605\u8bfb\u6e90\u7801\u4f60\u4e5f\u53ef\u4ee5\u5b66\u4e60\u5982\u4f55\u7f16\u5199\u4e00\u4e2a\u522b\u7684\u5e73\u53f0\u7684\u9002\u914d\u5668\u3002\u540e\u9762\u6211\u4eec\u4ece\u9002\u914d\u5668\u4e2d\u53d6\u51fa\u4e86\u7b2c\u4e00\u4e2a\u6536\u96c6\u5230\u7684\u535a\u6587\uff0c\u5e76\u4e14\u53d1\u9001\u81f3\u670d\u52a1\u5668\u7528\u4ee5\u6d4b\u8bd5\u4efb\u52a1 `Task`\uff0c\u8fd9\u662f [webhook/model/user.go](https://github.com/Drelf2018/webhook/blob/ad577b5f93a67820545b2cddc2a999c6a352dd3e/model/user.go#L40) \u4e2d\u5b9a\u4e49\u7684\u4e00\u79cd\u8bf7\u6c42\u7ed3\u6784\uff0c\u7528\u6765\u5b9e\u73b0\u5e7f\u64ad\u535a\u6587\uff0c\u4e5f\u5c31\u662f `webhook` \u7684\u5b9e\u73b0\u3002\n\n\u5e0c\u671b\u8fd9\u4e2a\u5de5\u5177\u5bf9\u4f60\u6709\u7528\uff01\n\n```py\nfrom qrcode import QRCode\n\nfrom submitter import Client, Task\nfrom submitter.adapter.weibo import Weibo\n\n\nclass AliClient(Client):\n def __init__(self, uid: str = \"\", password: str = \"\", token: str = \"\", ping: float = -1):\n super().__init__(\"http://gin.web-framework-m88s.1990019364850918.cn-hangzhou.fc.devsapp.net\", uid, password, token, ping)\n\n async def register(self) -> str:\n headers = {\n \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54\",\n \"Referer\": \"https://www.bilibili.com\",\n }\n resp = await self.session.get(\"https://passport.bilibili.com/x/passport-login/web/qrcode/generate\", headers=headers)\n result = resp.json()\n qr = QRCode(border=0)\n qr.add_data(result[\"data\"][\"url\"])\n qr.make()\n qr.print_ascii()\n input(\"\u626b\u63cf\u4e8c\u7ef4\u7801\u5b8c\u6210\u767b\u5f55\u540e\u6309\u4e0b\u56de\u8f66\u7ee7\u7eed\u6ce8\u518c\")\n data = {\n \"uid\": self.uid,\n \"password\": self.password,\n \"qrcode_key\": result[\"data\"][\"qrcode_key\"],\n }\n if await self.post(\"/register\", json=data) == \"success\":\n return await self.token(self.uid, self.password)\n\n\n@AliClient(uid=\"your_bilibili_uid\", password=\"the_account_password_you_want_to_use_to_submit_blog\")\nasync def main(self: AliClient):\n token = await self.register()\n self.log.info(f\"Token[{token}]\")\n # \u6ce8\u518c\u5b8c\u540e\u5c31\u53ef\u4ee5\u5427\u8fd9\u4e2a\u51fd\u6570\u5220\u4e86 \u7528\u4e0b\u9762\u90a3\u4e2a \u6ce8\u610f\u7528\u83b7\u53d6\u5230\u7684 Token \u66ff\u6362\u4e0b\u9762\u7684\u7a7a\u5b57\u7b26\u4e32\n\n@AliClient(ping=30, token=\"\")\nasync def ali(self: AliClient):\n async with Weibo(preload=[\"7198559139\"]) as w:\n for mid in w.blogs:\n log = await self.test(\n blog=w.blogs[mid],\n task=Task(\n public=True,\n enable=True,\n name=\"\u63a5\u6536\u6d4b\u8bd5\",\n method=\"POST\",\n url=\"https://httpbin.org/post\",\n body=\"{{ json . }}\",\n README=\"\u63a5\u6536\u6240\u6709\u5fae\u535a\",\n ),\n )\n self.log.info(log)\n break\n```\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\u57fa\u4e8e webhook \u7684\u535a\u6587\u63d0\u4ea4\u5668",
"version": "0.6.0",
"project_urls": {
"Homepage": "https://github.com/Drelf2018/submitter"
},
"split_keywords": [
"python",
" weibo",
" webhook"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c5c373d3ea606933098098b7e1e95f503c73440d25dc237a03a015ea0c4e3091",
"md5": "535185d9277f35d43bd017c87f6c3df8",
"sha256": "03c09a1482a3b83c1b98ccc1b3f90dd5e7407abf9c6c2cca075c97ba6122e7b7"
},
"downloads": -1,
"filename": "post_submitter-0.6.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "535185d9277f35d43bd017c87f6c3df8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 29494,
"upload_time": "2024-12-11T10:40:54",
"upload_time_iso_8601": "2024-12-11T10:40:54.341822Z",
"url": "https://files.pythonhosted.org/packages/c5/c3/73d3ea606933098098b7e1e95f503c73440d25dc237a03a015ea0c4e3091/post_submitter-0.6.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b5962f48ade2018c8ed128fdebe011996bfdb9df1cd3d76a35cb5d94b813c7a1",
"md5": "abd44ec900ad5ad324d858af7f8d6f64",
"sha256": "3eee007899a509f1f6ac37eeda62afb582036716d3c8ee89ff5d2a30efd8308e"
},
"downloads": -1,
"filename": "post-submitter-0.6.0.tar.gz",
"has_sig": false,
"md5_digest": "abd44ec900ad5ad324d858af7f8d6f64",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 26653,
"upload_time": "2024-12-11T10:40:56",
"upload_time_iso_8601": "2024-12-11T10:40:56.589493Z",
"url": "https://files.pythonhosted.org/packages/b5/96/2f48ade2018c8ed128fdebe011996bfdb9df1cd3d76a35cb5d94b813c7a1/post-submitter-0.6.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-11 10:40:56",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Drelf2018",
"github_project": "submitter",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "APScheduler",
"specs": [
[
"==",
"3.10.4"
]
]
},
{
"name": "emoji",
"specs": [
[
"==",
"2.14.0"
]
]
},
{
"name": "httpx",
"specs": [
[
"==",
"0.28.0"
]
]
},
{
"name": "loguru",
"specs": [
[
"==",
"0.7.2"
]
]
},
{
"name": "lxml",
"specs": [
[
"==",
"5.3.0"
]
]
},
{
"name": "Pillow",
"specs": [
[
"==",
"11.0.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
"==",
"2.10.2"
]
]
},
{
"name": "qrcode",
"specs": [
[
"==",
"7.4.2"
]
]
}
],
"lcname": "post-submitter"
}