From 8d46ed36a9d70c77ecad9d331102d91873468403 Mon Sep 17 00:00:00 2001 From: WangNingkai <1655586865@qq.com> Date: Tue, 11 Aug 2020 08:58:47 +0800 Subject: [PATCH] :sparkles: fistr commit first commit --- .github/workflows/main.yml | 36 +++++++++ .gitignore | 5 ++ LICENSE | 21 +++++ README.md | 59 ++++++++++++++ main.py | 156 +++++++++++++++++++++++++++++++++++++ requirements.text | 2 + 6 files changed, 279 insertions(+) create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 main.py create mode 100644 requirements.text diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..076ff96 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,36 @@ +name: 'Push News' + +on: + push: + branches: + - master + schedule: + - cron: '0 */3 * * *' + watch: + types: [started] + +env: + TZ: Asia/Shanghai + +jobs: + Gitfolio-Spider: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: 'Set up Python' + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: 'Install dependencies' + run: python -m pip install --upgrade pip + - name: 'Install requirements' + run: pip install -r ./requirements.txt + - name: 'Working' + env: + SECRET: ${{ secrets.SECRET }} + timeout-minutes: 350 + run: | + echo SECRET=$SECRET > .env + python main.py + rm -f .env diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b35a4c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Editor files and folders +.vscode/ +.idea/ +# env file +.env \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5887b7d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 WangNingkai + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b193576 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +## Serve酱自动推送热门 + +> 🔝 通过Serve酱自动发送微博、知乎、v2ex热门内容到微信,可自定义发送周期 + + +自动将V站、微博、知乎热门发送到指定的微信账号。可配置 workflow 的触发条件为 schedule,实现周期性定时发送热门内容。 + +### 示例 + +clone 此 GitHub 仓库,修改.github/workflows/ 文件夹下一个 main.yml 文件,内容如下: + +``` +name: 'Push News' + +on: + push: + branches: + - master + schedule: + - cron: '0 */3 * * *' # 定义 cron 表达式 + watch: + types: [started] # 定义star是自动发送 + +env: + TZ: Asia/Shanghai + +jobs: + Gitfolio-Spider: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: 'Set up Python' + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: 'Install dependencies' + run: python -m pip install --upgrade pip + - name: 'Install requirements' + run: pip install -r ./requirements.txt + - name: 'Working' + env: + SECRET: ${{ secrets.SECRET }} + timeout-minutes: 350 + run: | + echo SECRET=$SECRET > .env + python main.py + rm -f .env + +``` + +**注意** + +- cron 是 UTC 时间,使用时请将北京时间转换为 UTC 进行配置。 +- 请在项目的 Settings -> Secrets 路径下配置好SECRET(server酱密钥),不要直接在 .yml 文件中暴露地址跟密钥 + +### 效果 + +![](https://cdn.jsdelivr.net/gh/wangningkai/wangningkai/assets/20200811085352.png) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..56110c0 --- /dev/null +++ b/main.py @@ -0,0 +1,156 @@ +import json +import os +import random +from datetime import datetime +from urllib import parse + +import requests +from dotenv import find_dotenv, load_dotenv + +USER_AGENTS = [ + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; " + "SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; " + "SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", + "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; " + "Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", + "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; " + "Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; " + ".NET CLR 2.0.50727; Media Center PC 6.0)", + "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; " + "Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; " + ".NET CLR 3.5.30729; .NET CLR 3.0.30729; " + ".NET CLR 1.0.3705; .NET CLR 1.1.4322)", + "Mozilla/4.0 (compatible; MSIE 7.0b; " + "Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; " + "InfoPath.2; .NET CLR 3.0.04506.30)", + "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) " + "AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) " + "Arora/0.3 (Change: 287 c9dfb30)", + "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ " + "(KHTML, like Gecko, Safari/419.3) Arora/0.6", + "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; " + "rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", + "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) " + "Gecko/20080705 Firefox/3.0 Kapiko/3.0", + "Mozilla/5.0 (X11; Linux i686; U;) " + "Gecko/20070322 Kazehakase/0.4.5", + "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) " + "Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 " + "(KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) " + "AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", + "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) " + "Presto/2.9.168 Version/11.52" +] +TIMEOUT = 5 + + +class Action: + """V2EX Action""" + + def __init__(self): + load_dotenv(find_dotenv(), override=True) + self.secret = os.environ.get('SECRET') + self.contents = [] + self.res = False + + def servechan(self): + """调用serverchan接口""" + dt = datetime.now() + time = dt.strftime('%Y-%m-%d') + url = f'https://sc.ftqq.com/{self.secret}.send' + data = { + 'text': f'资讯热文推送-{time}', + 'desp': f'{"".join(self.contents)}' + } + headers = {'Content-Type': 'application/x-www-form-urlencoded'} + try: + resp = requests.post(url, headers=headers, + data=parse.urlencode(data), timeout=TIMEOUT) + self.res = resp.json()['errno'] == 0 + print(resp.text) + except Exception as e: + print(f'something error occurred, message: {e}') + + @staticmethod + def get_v2ex_hot_topics(): + """获取V站热门主题""" + url = 'https://www.v2ex.com/api/topics/hot.json' + headers = {'User-Agent': random.choice(USER_AGENTS)} + contents = [] + try: + resp = requests.get(url, headers=headers, timeout=TIMEOUT) + json_data = json.loads(resp.text) + for item in json_data: + detail_url = item['url'] + title = item['title'] + content = f'- [{title}]({detail_url})\n' + contents.append(content) + return contents + except Exception as e: + print(f'something error occurred, message: {e}') + return [] + + @staticmethod + def get_zhihu_hot_topics(): + url = "https://bicido.com/api/news/?type_id=4" + headers = { + 'Referer': 'https://bicido.com/', + 'Host': 'bicido.com', + 'User-Agent': random.choice(USER_AGENTS) + } + contents = [] + try: + resp = requests.get(url, headers=headers, timeout=TIMEOUT) + json_data = json.loads(resp.text) + for item in json_data: + detail_url = item['source_url'] + title = item['title'] + content = f'- [{title}]({detail_url})\n' + contents.append(content) + return contents + except Exception as e: + print(f'something error occurred, message: {e}') + return [] + + @staticmethod + def get_weibo_hot_topics(): + url = "https://bicido.com/api/news/?type_id=1" + headers = { + 'Referer': 'https://bicido.com/', + 'Host': 'bicido.com', + 'User-Agent': random.choice(USER_AGENTS) + } + contents = [] + try: + resp = requests.get(url, headers=headers, timeout=TIMEOUT) + json_data = json.loads(resp.text) + for item in json_data: + detail_url = item['source_url'] + title = item['title'] + content = f'- [{title}]({detail_url})\n' + contents.append(content) + return contents + except Exception as e: + print(f'something error occurred, message: {e}') + return [] + + def run(self): + """主方法""" + weibo_contents = Action.get_weibo_hot_topics() + weibo_contents.insert(0, f'\n> 微博热搜\n\n') + zhihu_contents = Action.get_zhihu_hot_topics() + zhihu_contents.insert(0, f'\n> 知乎热榜\n\n') + v2ex_contents = Action.get_v2ex_hot_topics() + v2ex_contents.insert(0, f'\n> v2ex热搜\n\n') + self.contents = weibo_contents+zhihu_contents+v2ex_contents + self.servechan() + # print(f'{"".join(self.contents)}') + + +if __name__ == '__main__': + action = Action() + action.run() diff --git a/requirements.text b/requirements.text new file mode 100644 index 0000000..d44fe44 --- /dev/null +++ b/requirements.text @@ -0,0 +1,2 @@ +requests +python-dotenv \ No newline at end of file