├── .gitignore ├── LICENSE ├── README.md ├── api ├── baidu │ ├── api.py │ └── js │ │ └── translate.js ├── google │ ├── api.py │ └── js │ │ └── translate.js ├── main.py ├── tools │ └── api.py ├── weibo │ └── api.py └── youdao │ └── api.py ├── favicon.ico ├── requirements.txt ├── settings.py └── vercel.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # test module 个人习惯,测试目录去掉 10 | /test/ 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | .idea/ 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # celery beat schedule file 90 | celerybeat-schedule 91 | 92 | # SageMath parsed files 93 | *.sage.py 94 | 95 | # Environments 96 | .env 97 | .venv 98 | env/ 99 | venv/ 100 | ENV/ 101 | env.bak/ 102 | venv.bak/ 103 | 104 | # Spyder project settings 105 | .spyderproject 106 | .spyproject 107 | 108 | # Rope project settings 109 | .ropeproject 110 | 111 | # mkdocs documentation 112 | /site 113 | 114 | # mypy 115 | .mypy_cache/ 116 | .dmypy.json 117 | dmypy.json 118 | 119 | # Pyre type checker 120 | .pyre/ 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eurkon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 本文收集了常用的 API 接口以及自己部署于 Vercel 的 Python API 合集。 4 | 5 | ## 自建 API 6 | 7 | ### 百度 8 | 9 | #### 百度统计 10 | 11 | **接口地址:** /baidu/tongji 12 | 13 | **描述:** 重定向请求百度统计,解决跨域问题 14 | 15 | **请求方式:** GET 16 | 17 | **请求参数说明:** [百度统计用户手册](https://tongji.baidu.com/api/manual/) 18 | 19 | **请求示例:** 无 20 | 21 | #### 百度翻译 22 | 23 | **接口地址:** /baidu/translate 24 | 25 | **描述:** 百度翻译 26 | 27 | **请求方式:** GET 28 | 29 | **请求参数说明:** 30 | 31 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 32 | | --- | --- | --- | --- | --- | 33 | | fr | 源语言 | string | 英语 | 否 | 34 | | to | 翻译语言 | string | 中文 | 否 | 35 | | content | 源语言 | string | Hello World | 否 | 36 | 37 | **请求示例:** https://api.eurkon.com/baidu/translate?fr=英语&to=中文&content=helloworld 38 | 39 | 40 | ### 谷歌 41 | 42 | #### 谷歌翻译 43 | 44 | **接口地址:** /google/translate 45 | 46 | **描述:** 谷歌翻译 47 | 48 | **请求方式:** GET 49 | 50 | **请求参数说明:** 51 | 52 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 53 | | --- | --- | --- | --- | --- | 54 | | fr | 源语言 | string | 英语 | 否 | 55 | | to | 翻译语言 | string | 中文 | 否 | 56 | | content | 翻译内容 | string | Hello World | 否 | 57 | 58 | **请求示例:** https://api.eurkon.com/google/translate?fr=英语&to=中文&content=helloworld 59 | 60 | 61 | ### 微博 62 | 63 | #### 微博热搜 64 | 65 | **接口地址:** /weibo/top 66 | 67 | **描述:** 爬取微博热搜 68 | 69 | **请求方式:** GET 70 | 71 | **请求参数说明:** 无 72 | 73 | **请求示例:** https://api.eurkon.com/weibo/top 74 | 75 | ### 工具 76 | 77 | #### 生成二维码 78 | 79 | **接口地址:** /tools/qrcode 80 | 81 | **描述:** 重定向请求百度统计,解决跨域问题 82 | 83 | **请求方式:** GET 84 | 85 | **请求参数说明:** 86 | 87 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 88 | | --- | --- | --- | --- | --- | 89 | | content | 二维码内容 | string | Hello World | 否 | 90 | 91 | **请求示例:** https://api.eurkon.com/api?api=tools_qrcode&content=HelloWorld 92 | 93 | 94 | ### 有道 95 | 96 | #### 有道翻译 97 | 98 | **接口地址:** /youdao/translate 99 | 100 | **描述:** 有道翻译 101 | 102 | **请求方式:** GET 103 | 104 | **请求参数说明:** 105 | 106 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 107 | | --- | --- | --- | --- | --- | 108 | | content | 翻译内容 | string | Hello World | 否 | 109 | 110 | **请求示例:** https://api.eurkon.com/youdao/translate?content=helloworld 111 | 112 | 113 | ## 常用 API 114 | 115 | ### 百度百科历史今日 116 | 117 | **接口地址:** https://baike.baidu.com/cms/home/eventsOnHistory/ 118 | 119 | **描述:** 百度百科历史今日 120 | 121 | **请求方式:** GET 122 | 123 | **请求参数说明:** 124 | 125 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 126 | | --- | --- | --- | --- | --- | 127 | | month | 月份 | string | 无 | 是 | 128 | 129 | **请求示例:** https://baike.baidu.com/cms/home/eventsOnHistory/01.json 130 | 131 | ### IP、行政区编码、地址 132 | 133 | **接口地址:** https://pv.sohu.com/cityjson 134 | 135 | **描述:** 获取当前 IP 地址信息 136 | 137 | **请求方式:** GET 138 | 139 | **请求参数说明:** 无 140 | 141 | **请求示例:** https://pv.sohu.com/cityjson?ie=utf-8 142 | 143 | ### 地区、国家、天气、温度、湿度 144 | 145 | **接口地址:** https://wttr.in/ip 146 | 147 | **描述:** 获取当前 IP 地址和天气信息 148 | 149 | **请求方式:** GET 150 | 151 | **请求参数说明:** 152 | 153 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 154 | | --- | --- | --- | --- | --- | 155 | | format | 返回格式 | string | 无 | 否 | 156 | 157 | **请求示例:** https://wttr.in/ip?format="%l+\\+%c+\\+%t+\\+%h" 158 | 159 | ### 腾讯天气接口 160 | 161 | **接口地址:** https://wis.qq.com/weather/common 162 | 163 | **描述:** 获取当前 IP 地址和天气信息 164 | 165 | **请求方式:** GET 166 | 167 | **请求参数说明:** 168 | 169 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 170 | | --- | --- | --- | --- | --- | 171 | | source | 请求类型 pc/wx | string | 无 | 是 | 172 | | weather_type | 查询类型,多个用 | 分隔
observe(当前天气)
forecast_1h
forecast_24h
index 穿衣,舒适度等
alarm(预警)
tips(天气介绍)
air(空气质量)
rise(日出)| string | 无 | 是 | 173 | | province | 省份 | string | 无 | 是 | 174 | | city | 城市 | string | 无 | 是 | 175 | | county | 县区 | string | 无 | 否 | 176 | | callback | 回调函数,不传直接返回 json | string | 无 | 否 | 177 | 178 | **请求示例:** https://wis.qq.com/weather/common?source=xw&weather_type=forecast_1h|forecast_24h|index|alarm|limit|tips&province=广东&city=广州&county=天河 179 | 180 | ### 豆瓣电影接口 181 | 182 | **接口地址:** https://movie.douban.com/j/search_subjects 183 | 184 | **描述:** 获取当前 IP 地址和天气信息 185 | 186 | **请求方式:** GET 187 | 188 | **请求参数说明:** 189 | 190 | 参考页面:https://movie.douban.com/explore 191 | 192 | | 字段名 | 字段说明 | 字段类型 | 默认值 | 是否必填 | 193 | | --- | --- | --- | --- | --- | 194 | | tag | 标签 | string | 无 | 否 | 195 | | type | 类型 | string | movie | 否 | 196 | | sort | 排序 | string | recommend | 否 | 197 | | page_limit | 返回个数 | integer | 20 | 否 | 198 | | page_start | 开始索引 | integer | 0 | 否 | 199 | 200 | **请求示例:** https://movie.douban.com/j/search_subjects?type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0 201 | 202 | ## 常用 API 网站 203 | 204 | ### [博天 API](https://api.btstu.cn/) 205 | 206 | - **随机壁纸**:随机输出各类壁纸 207 | - **毒鸡汤**:随机输出毒鸡汤 208 | - **随机头像**:随机输出各类头像 209 | - **获取 QQ 昵称和头像**:获取 QQ 昵称和头像 210 | - **ICP 备案查询**:在线查询网站 ICP 备案 211 | - **QQ 信息查询**:查询 QQ 的信息 212 | - **QQ 域名报毒检测**:检测域名在 QQ 是否报毒 213 | - **二维码解码**:解析二维码图片 214 | - **Qrcode 二维码**:生成在线二维码 215 | - **域名注册查询**:查询域名是否已被注册 216 | - **搜狗收录量**:查询搜狗收录数量 217 | - **在线 ping**:在线 ping 网站 218 | - **百度收录量**:查询域名百度收录总量 219 | - **IP 签名档**:输出精美 IP 信息图 220 | - **抖音网址检测**:检测网址是否可以在抖音直接打开 221 | - **百度收录判断**:判断网址是否已被百度收录 222 | - **QQ 强制聊天**:无需添加 QQ 好友,直接进入聊天 223 | - **域名过期查询**:查询域名的注册时间与到期时间 224 | - **抖音解析**:解析抖音链接,获取无水印链接 225 | - **语言翻译**:自动识别并翻译 226 | - **QQ 电脑在线状态**:查询 QQ 的电脑在线状态 227 | - **微信域名安全检测**:检测域名在微信是否报毒 228 | - **mrw.so 短网址**:提供 mrw.so 短网址的生成与还原服务 229 | - **机器人云黑名单**:查询各类自动进群机器人等等 230 | - **网站 favicon 图标获取**:获取网站的 favicon.ico 图标 231 | - **网易云音乐解析**:在线解析网易云音乐 232 | - **QQ 手游+微视一键加速**:QQ 手游+微视一键加速(0.2+0.5)天 233 | - **三合一收款码**:合并 QQ,微信和支付宝收款码为一个二维码 234 | - **获取 QQ 群加群链接**:只需要 QQ 群号码即可获取加群链接 235 | 236 | ## 持续更新中... 237 | -------------------------------------------------------------------------------- /api/baidu/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2021/6/9 17:13 4 | 5 | import requests 6 | import re 7 | import execjs 8 | 9 | 10 | def tongji(params): 11 | """重定向请求百度统计,解决跨域问题 12 | 13 | Args: 14 | params: {site_id: 网站id, access_token: token, ...} 15 | 16 | Returns: 17 | dict: 百度统计返回的网页统计数据 18 | """ 19 | url = 'https://openapi.baidu.com/rest/2.0/tongji/report/getData?' 20 | req = requests.post(url=url, data=params) 21 | data = req.json() 22 | 23 | return data 24 | 25 | 26 | def translate(fr: str = '英语', to: str = '中文', content: str = 'Hello World'): 27 | """百度翻译 28 | 29 | Args: 30 | fr: 源语言 31 | to: 翻译语言 32 | content: 翻译内容 33 | 34 | Returns: 35 | dict: {result: 翻译后的内容} 36 | """ 37 | lang_dict = {'中文': 'zh', '日语': 'jp', '日语假名': 'jpka', '泰语': 'th', '法语': 'fra', '英语': 'en', '西班牙语': 'spa', 38 | '韩语': 'kor', 39 | '土耳其语': 'tr', '越南语': 'vie', '马来语': 'ms', '德语': 'de', '俄语': 'ru', '伊朗语': 'ir', '阿拉伯语': 'ara', 40 | '爱沙尼亚语': 'est', 41 | '白俄罗斯语': 'be', '保加利亚语': 'bul', '印地语': 'hi', '冰岛语': 'is', '波兰语': 'pl', '波斯语': 'fa', '丹麦语': 'dan', 42 | '菲律宾语': 'tl', 43 | '芬兰语': 'fin', '荷兰语': 'nl', '加泰罗尼亚语': 'ca', '捷克语': 'cs', '克罗地亚语': 'hr', '拉脱维亚语': 'lv', '立陶宛语': 'lt', 44 | '罗马尼亚语': 'rom', 45 | '南非语': 'af', '挪威语': 'no', '巴西语': 'pt_BR', '葡萄牙语': 'pt', '瑞典语': 'swe', '塞尔维亚语': 'sr', '世界语': 'eo', 46 | '斯洛伐克语': 'sk', 47 | '斯洛文尼亚语': 'slo', '斯瓦希里语': 'sw', '乌克兰语': 'uk', '希伯来语': 'iw', '希腊语': 'el', '匈牙利语': 'hu', '亚美尼亚语': 'hy', 48 | '意大利语': 'it', 49 | '印尼语': 'id', '阿尔巴尼亚语': 'sq', '阿姆哈拉语': 'am', '阿萨姆语': 'as', '阿塞拜疆语': 'az', '巴斯克语': 'eu', '孟加拉语': 'bn', 50 | '波斯尼亚语': 'bs', 51 | '加利西亚语': 'gl', '格鲁吉亚语': 'ka', '古吉拉特语': 'gu', '豪萨语': 'ha', '伊博语': 'ig', '因纽特语': 'iu', '爱尔兰语': 'ga', 52 | '祖鲁语': 'zu', 53 | '卡纳达语': 'kn', '哈萨克语': 'kk', '吉尔吉斯语': 'ky', '卢森堡语': 'lb', '马其顿语': 'mk', '马耳他语': 'mt', '毛利语': 'mi', 54 | '马拉提语': 'mr', 55 | '尼泊尔语': 'ne', '奥利亚语': 'or', '旁遮普语': 'pa', '凯楚亚语': 'qu', '塞茨瓦纳语': 'tn', '僧加罗语': 'si', '泰米尔语': 'ta', 56 | '塔塔尔语': 'tt', 57 | '泰卢固语': 'te', '乌尔都语': 'ur', '乌兹别克语': 'uz', '威尔士语': 'cy', '约鲁巴语': 'yo', '粤语': 'yue', '文言文': 'wyw', 58 | '中文繁体': 'cht'} 59 | 60 | url = 'https://fanyi.baidu.com/v2transapi' 61 | headers = { 62 | 'Referer': 'https://fanyi.baidu.com/?aldtype=16047', 63 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' 64 | } 65 | 66 | # 多次请求保证获取 token,并用此 token 进行翻译 67 | session = requests.Session() 68 | session.headers = headers 69 | session.get(url='https://fanyi.baidu.com/') 70 | html = session.get(url='https://fanyi.baidu.com/').text 71 | token = re.findall(r"token: '(.*?)'", html)[0] 72 | gtk = re.findall(r"window.gtk = '(.*?)';", html)[0] 73 | 74 | js_text = """ 75 | function a (r) { 76 | if (Array.isArray(r)) { 77 | for (var o = 0, 78 | t = Array(r.length); o < r.length; o++) t[o] = r[o]; 79 | return t 80 | } 81 | return Array.from(r) 82 | } 83 | 84 | function n (r, o) { 85 | for (var t = 0; t < o.length - 2; t += 3) { 86 | var a = o.charAt(t + 2); 87 | a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), 88 | a = "+" === o.charAt(t + 1) ? r >>> a : r << a, 89 | r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a 90 | } 91 | return r 92 | } 93 | 94 | function e (r, u) { 95 | var o = r.match(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g); 96 | if (null === o) { 97 | var t = r.length; 98 | t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(- 10, 10)); 99 | } else { 100 | for (var e = r.split(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)"" !== e[C] && f.push.apply(f, a(e[C].split(""))), 101 | C !== h - 1 && f.push(o[C]); 102 | var g = f.length; 103 | g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(- 10).join("")); 104 | } 105 | 106 | var l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); 107 | for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { 108 | var A = r.charCodeAt(v); 109 | 128 > A ? (S[c++] = A) : (2048 > A ? (S[c++] = (A >> 6) | 192) : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? ((A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v))), (S[c++] = (A >> 18) | 240), (S[c++] = ((A >> 12) & 63) | 128)) : (S[c++] = (A >> 12) | 224), (S[c++] = ((A >> 6) & 63) | 128)), (S[c++] = (63 & A) | 128)); 110 | } 111 | for (var p = m, 112 | F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)(p += S[b]), 113 | (p = n(p, F)); 114 | return ((p = n(p, D)), (p ^= s), 0 > p && (p = (2147483647 & p) + 2147483648), (p %= 1e6), p.toString() + "." + (p ^ m)); 115 | } 116 | """ 117 | 118 | # with open('js/translate.js', 'r', encoding='UTF-8') as file: 119 | # js_text = file.read() 120 | # 编译加载js字符串 121 | js = execjs.compile(js_text) 122 | sign = js.call("e", str(content), gtk) 123 | 124 | params = { 125 | 'from': lang_dict[fr], 126 | 'to': lang_dict[to], 127 | 'query': content, 128 | 'simple_means_flag': '3', 129 | 'sign': sign, 130 | 'token': token, 131 | 'domain': 'common' 132 | } 133 | 134 | response = session.get(url=url, params=params) 135 | message = response.json() 136 | return {'result': message['trans_result']['data'][0]['dst']} 137 | -------------------------------------------------------------------------------- /api/baidu/js/translate.js: -------------------------------------------------------------------------------- 1 | function a (r) { 2 | if (Array.isArray(r)) { 3 | for (var o = 0, 4 | t = Array(r.length); o < r.length; o++) t[o] = r[o]; 5 | return t 6 | } 7 | return Array.from(r) 8 | } 9 | 10 | function n (r, o) { 11 | for (var t = 0; t < o.length - 2; t += 3) { 12 | var a = o.charAt(t + 2); 13 | a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), 14 | a = "+" === o.charAt(t + 1) ? r >>> a : r << a, 15 | r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a 16 | } 17 | return r 18 | } 19 | 20 | function e (r, u) { 21 | var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); 22 | if (null === o) { 23 | var t = r.length; 24 | t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(- 10, 10)); 25 | } else { 26 | for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)"" !== e[C] && f.push.apply(f, a(e[C].split(""))), 27 | C !== h - 1 && f.push(o[C]); 28 | var g = f.length; 29 | g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(- 10).join("")); 30 | } 31 | 32 | var l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); 33 | for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { 34 | var A = r.charCodeAt(v); 35 | 128 > A ? (S[c++] = A) : (2048 > A ? (S[c++] = (A >> 6) | 192) : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? ((A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v))), (S[c++] = (A >> 18) | 240), (S[c++] = ((A >> 12) & 63) | 128)) : (S[c++] = (A >> 12) | 224), (S[c++] = ((A >> 6) & 63) | 128)), (S[c++] = (63 & A) | 128)); 36 | } 37 | for (var p = m, 38 | F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)(p += S[b]), 39 | (p = n(p, F)); 40 | return ((p = n(p, D)), (p ^= s), 0 > p && (p = (2147483647 & p) + 2147483648), (p %= 1e6), p.toString() + "." + (p ^ m)); 41 | } 42 | -------------------------------------------------------------------------------- /api/google/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2021/6/10 10:41 4 | 5 | import execjs 6 | import requests 7 | 8 | 9 | def translate(fr: str = '英语', to: str = '中文', content: str = 'Hello World'): 10 | """谷歌翻译 11 | 12 | Args: 13 | fr: 源语言 14 | to: 翻译语言 15 | content: 翻译内容 16 | 17 | Returns: 18 | dict: {result: 翻译后的内容} 19 | """ 20 | lang_dict = {'中文': 'zh-CN', '阿尔巴尼亚语': 'sq', '阿拉伯语': 'ar', 21 | '阿姆哈拉语': 'am', '阿塞拜疆语': 'az', '爱尔兰语': 'ga', 22 | '爱沙尼亚语': 'et', '巴斯克语': 'eu', '白俄罗斯语': 'be', 23 | '保加利亚语': 'bg', '冰岛语': 'is', '波兰语': 'pl', '波斯尼亚语': 'bs', 24 | '波斯语': 'fa', '布尔语': 'af', '丹麦语': 'da', '德语': 'de', '俄语': 'ru', '法语': 'fr', 25 | '菲律宾语': 'tl', '芬兰语': 'fi', '弗里西语': 'fy', '高棉语': 'km', '格鲁吉亚语': 'ka', 26 | '古吉拉特语': 'gu', '哈萨克语': 'kk', '海地克里奥尔语': 'ht', '韩语': 'ko', 27 | '豪萨语': 'ha', '荷兰语': 'nl', '吉尔吉斯语': 'ky', '加利西亚语': 'gl', '加泰罗尼亚语': 'ca', 28 | '捷克语': 'cs', '卡纳达语': 'kn', '科西嘉语': 'co', '克罗地亚语': 'hr', 29 | '库尔德语': 'ku', '拉丁语': 'la', '拉脱维亚语': 'lv', '老挝语': 'lo', '立陶宛语': 'lt', 30 | '卢森堡语': 'lb', '罗马尼亚语': 'ro', '马尔加什语': 'mg', '马耳他语': 'mt', 31 | '马拉地语': 'mr', '马拉雅拉姆语': 'mf', '马来语': 'ms', '马其顿语': 'mk', 32 | '毛利语': 'mi', '蒙古语': 'mn', '孟加拉语': 'bn', '缅甸语': 'my', '苗语': 'hmn', '南非克萨语': 'xh', '南非祖鲁语': 'zu', 33 | '尼泊尔语': 'ne', '挪威语': 'no', '旁遮普语': 'pa', '葡萄牙语': 'pt', '普什图语': 'ps', 34 | '齐切瓦语': 'ny', '日语': 'ja', '瑞典语': 'sv', '萨摩亚语': 'sm', '塞尔维亚语': 'sr', 35 | '赛所托语': 'st', '僧伽罗语': 'si', '世界语': 'eo', '斯洛伐克语': 'sk', '斯洛文尼亚语': 'sl', 36 | '斯瓦希里语': 'sw', '苏格兰盖尔语': 'gd', '宿务语': 'ceb', '索马里语': 'so', '塔吉克语': 'tg', '泰卢固语': 'te', 37 | '泰米尔语': 'ta', '泰语': 'th', '土耳其语': 'tr', '威尔士语': 'cy', '乌尔都语': 'ur', 38 | '乌克兰语': 'uk', '乌兹别克语': 'uz', '西班牙语': 'es', '希伯来语': 'rw', '希腊语': 'el', 39 | '夏威夷语': 'haw', '信德语': 'sd', '匈牙利语': 'hu', '修纳语': 'sn', 40 | '亚美尼亚语': 'hy', '伊博语': 'ig', '意大利语': 'it', '意第绪语': 'yi', '印地语': 'hi', 41 | '印尼巽他': 'su', '印尼语': 'id', '印尼爪哇语': 'jw', '英语': 'en', '约鲁巴语': 'yo', '越南语': 'vi', '中文繁体': 'zh-TW'} 42 | 43 | js_text = """ 44 | function TL(a) { 45 | var k = ""; 46 | var b = 406644; 47 | var b1 = 3293161072; 48 | var jd = "."; 49 | var $b = "+-a^+6"; 50 | var Zb = "+-3^+b+-f"; 51 | for (var e = [], f = 0, g = 0; g < a.length; g++) { 52 | var m = a.charCodeAt(g); 53 | 128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023), 54 | e[f++] = m >> 18 | 240, 55 | e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224, 56 | e[f++] = m >> 6 & 63 | 128), 57 | e[f++] = m & 63 | 128) 58 | } 59 | a = b; 60 | for (f = 0; f < e.length; f++) a += e[f], 61 | a = RL(a, $b); 62 | a = RL(a, Zb); 63 | a ^= b1 || 0; 64 | 0 > a && (a = (a & 2147483647) + 2147483648); 65 | a %= 1E6; 66 | return a.toString() + jd + (a ^ b) 67 | }; 68 | 69 | function RL(a, b) { 70 | var t = "a"; 71 | var Yb = "+"; 72 | for (var c = 0; c < b.length - 2; c += 3) { 73 | var d = b.charAt(c + 2), 74 | d = d >= t ? d.charCodeAt(0) - 87 : Number(d), 75 | d = b.charAt(c + 1) == Yb ? a >>> d : a << d; 76 | a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d 77 | } 78 | return a 79 | } 80 | """ 81 | # with open('../js/translate.js', 'r', encoding='UTF-8') as file: 82 | # js_text = file.read() 83 | # 编译加载js字符串 84 | js = execjs.compile(js_text) 85 | tk = js.call("TL", content) 86 | 87 | if len(content) > 4891: 88 | return {'error': '内容过长'} 89 | else: 90 | url = "http://translate.google.cn/translate_a/single?client=t" \ 91 | "&sl={}&tl={}&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca" \ 92 | "&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&clearbtn=1&otf=1&pc=1" \ 93 | "&srcrom=0&ssel=0&tsel=0&kc=2&tk={}&q={}".format(lang_dict[fr], lang_dict[to], tk, content) 94 | headers = { 95 | 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36', 96 | 'referer': 'https://translate.google.cn/', 97 | 'authority': 'translate.google.cn' 98 | } 99 | response = requests.get(url=url, headers=headers) 100 | 101 | end = response.text.find("\",") 102 | if end > 4: 103 | message = response.text[4:end] 104 | else: 105 | return {'error': '翻译失败'} 106 | return {'result': message} 107 | 108 | 109 | if __name__ == '__main__': 110 | print(translate(fr='英语', to='中文', content='Hello World')) 111 | -------------------------------------------------------------------------------- /api/google/js/translate.js: -------------------------------------------------------------------------------- 1 | function TL(a) { 2 | var k = ""; 3 | var b = 406644; 4 | var b1 = 3293161072; 5 | var jd = "."; 6 | var $b = "+-a^+6"; 7 | var Zb = "+-3^+b+-f"; 8 | for (var e = [], f = 0, g = 0; g < a.length; g++) { 9 | var m = a.charCodeAt(g); 10 | 128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023), 11 | e[f++] = m >> 18 | 240, 12 | e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224, 13 | e[f++] = m >> 6 & 63 | 128), 14 | e[f++] = m & 63 | 128) 15 | } 16 | a = b; 17 | for (f = 0; f < e.length; f++) a += e[f], 18 | a = RL(a, $b); 19 | a = RL(a, Zb); 20 | a ^= b1 || 0; 21 | 0 > a && (a = (a & 2147483647) + 2147483648); 22 | a %= 1E6; 23 | return a.toString() + jd + (a ^ b) 24 | }; 25 | 26 | function RL(a, b) { 27 | var t = "a"; 28 | var Yb = "+"; 29 | for (var c = 0; c < b.length - 2; c += 3) { 30 | var d = b.charAt(c + 2), 31 | d = d >= t ? d.charCodeAt(0) - 87 : Number(d), 32 | d = b.charAt(c + 1) == Yb ? a >>> d : a << d; 33 | a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d 34 | } 35 | return a 36 | } -------------------------------------------------------------------------------- /api/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2022/3/8 14:17 4 | 5 | import settings 6 | import uvicorn 7 | from fastapi import FastAPI, Request 8 | from fastapi.middleware.cors import CORSMiddleware 9 | from scrapy.utils.project import get_project_settings 10 | 11 | import api.baidu.api as baidu 12 | import api.google.api as google 13 | import api.weibo.api as weibo 14 | import api.youdao.api as youdao 15 | 16 | app = FastAPI() 17 | app.add_middleware(CORSMiddleware, 18 | allow_credentials=True, 19 | allow_origins=["*"], 20 | allow_methods=["*"], 21 | allow_headers=["*"] 22 | ) 23 | 24 | settings = get_project_settings() 25 | 26 | 27 | @app.get("/baidu/tongji", tags=["API"], summary="百度统计") 28 | def baidu_tongji(request: Request): 29 | """重定向请求百度统计,解决跨域问题 30 | 31 | Args: 32 | request: {site_id: 网站id, access_token: token, ...} 33 | 34 | Returns: 35 | json: 百度统计返回的网页统计数据 36 | """ 37 | return baidu.tongji(request.query_params) 38 | 39 | 40 | @app.get("/baidu/translate", tags=["API"], summary="百度翻译") 41 | def baidu_translate(fr: str = '英语', to: str = '中文', content: str = 'Hello World'): 42 | """百度翻译 43 | 44 | Args: 45 | fr: 源语言 46 | to: 翻译语言 47 | content: 翻译内容 48 | 49 | Returns: 50 | dict: {result: 翻译后的内容} 51 | """ 52 | return baidu.translate(fr, to, content) 53 | 54 | 55 | @app.get("/google/translate", tags=["API"], summary="谷歌翻译") 56 | def google_translate(fr: str = '英语', to: str = '中文', content: str = 'Hello World'): 57 | """谷歌翻译 58 | 59 | Args: 60 | fr: 源语言 61 | to: 翻译语言 62 | content: 翻译内容 63 | 64 | Returns: 65 | dict: {result: 翻译后的内容} 66 | """ 67 | return google.translate(fr, to, content) 68 | 69 | 70 | @app.get("/weibo/top", tags=["API"], summary="微博热搜") 71 | def weibo_top(): 72 | """微博热搜 73 | 74 | Args: 75 | 76 | Returns: 77 | list: [{title: 标题, url: 地址, num: 热度数值, hot: 热搜等级}, ...] 78 | """ 79 | return weibo.top() 80 | 81 | 82 | @app.post("/youdao/translate", tags=["API"], summary="有道翻译") 83 | async def youdao_translate(content: str = 'Hello World'): 84 | """有道翻译 85 | 86 | Args: 87 | content: 翻译内容 88 | 89 | Returns: 90 | dict: {result: 翻译后的内容} 91 | """ 92 | return youdao.translate(content) 93 | 94 | 95 | async def request(session, url): 96 | async with session.get(url) as response: 97 | return await response.text() 98 | 99 | 100 | if __name__ == "__main__": 101 | uvicorn.run("main:app", host="127.0.0.1") 102 | -------------------------------------------------------------------------------- /api/tools/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2021/6/15 9:44 4 | 5 | import io 6 | import os 7 | import qrcode 8 | from MyQR import myqr 9 | 10 | 11 | def qrcode(content: str = 'Hello World'): 12 | """生成二维码 13 | 14 | Args: 15 | content: 二维码内容 16 | 17 | Returns: 18 | bytes: 字节流 19 | """ 20 | 21 | img = qrcode.make(content) 22 | # 创建一个字节流管道 23 | img_bytes = io.BytesIO() 24 | # 将图片数据存入字节流管道, format可以按照具体文件的格式填写 25 | img.save(img_bytes, format="PNG") 26 | # 从字节流管道中获取二进制 27 | image_bytes = img_bytes.getvalue() 28 | return image_bytes 29 | 30 | 31 | def qrcode_colorized(words: str = 'Hello World', picture: str = None, colorized: str = False): 32 | """生成二维码 33 | 34 | Args: 35 | words: 内容(不能是中文) 36 | picture: 背景 37 | colorized: 是否为彩色 38 | 39 | Returns: 40 | str: 图片地址 41 | """ 42 | 43 | path = os.path.dirname(os.path.dirname(__file__)) + '/img/' 44 | name = 'qrcode.gif' if picture and picture[-4:] == '.gif' else 'qrcode.png' 45 | colorized = True if colorized and colorized.lower() == 'true' else False 46 | myqr.run(words=words, picture=picture, colorized=colorized, save_name=name, save_dir=path) 47 | 48 | return path + name 49 | 50 | 51 | if __name__ == '__main__': 52 | # print(qrcode({'words': 'https://blog.eurkon.com/', 53 | # 'picture': '../img/background.gif', 54 | # 'colorized': True})) 55 | print(qrcode('https://blog.eurkon.com/')) 56 | -------------------------------------------------------------------------------- /api/weibo/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2021/6/5 10:16 4 | 5 | import requests 6 | 7 | 8 | def top(): 9 | """微博热搜 10 | 11 | Args: 12 | 13 | Returns: 14 | list: [{title: 标题, url: 地址, num: 热度数值, hot: 热搜等级}, ...] 15 | """ 16 | 17 | data = [] 18 | response = requests.get("https://weibo.com/ajax/side/hotSearch") 19 | data_json = response.json()['data']['realtime'] 20 | jyzy = { 21 | '电影': '影', 22 | '剧集': '剧', 23 | '综艺': '综', 24 | '音乐': '音' 25 | } 26 | 27 | for data_item in data_json: 28 | hot = '' 29 | # 如果是广告,则不添加 30 | if 'is_ad' in data_item: 31 | continue 32 | if 'flag_desc' in data_item: 33 | hot = jyzy.get(data_item['flag_desc']) 34 | if 'is_boom' in data_item: 35 | hot = '爆' 36 | if 'is_hot' in data_item: 37 | hot = '热' 38 | if 'is_fei' in data_item: 39 | hot = '沸' 40 | if 'is_new' in data_item: 41 | hot = '新' 42 | 43 | dic = { 44 | 'title': data_item['note'], 45 | 'url': 'https://s.weibo.com/weibo?q=%23' + data_item['word'] + '%23', 46 | 'num': data_item['num'], 47 | 'hot': hot 48 | } 49 | data.append(dic) 50 | 51 | return data 52 | -------------------------------------------------------------------------------- /api/youdao/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author : Eurkon 3 | # @Date : 2021/11/10 16:32 4 | 5 | import requests 6 | from hashlib import md5 7 | import time 8 | import random 9 | 10 | 11 | def translate(content: str = 'Hello World'): 12 | """有道翻译 13 | 14 | Args: 15 | content: 翻译内容 16 | 17 | Returns: 18 | dict: {result: 翻译后的内容} 19 | """ 20 | # 请求地址 21 | url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' 22 | 23 | appVersion = '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36' 24 | 25 | headers = { 26 | 'Accept': 'application/json, text/javascript, */*; q=0.01', 27 | 'Accept-Encoding': 'gzip, deflate', 28 | 'Accept-Language': 'zh-CN,zh;q=0.9', 29 | 'Connection': 'keep-alive', 30 | 'Content-Length': '244', 31 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 32 | 'Cookie': 'OUTFOX_SEARCH_USER_ID=-1506602845@10.169.0.82; JSESSIONID=aaaUggpd8kfhja1AIJYpx; OUTFOX_SEARCH_USER_ID_NCOO=108436537.92676207; ___rl__test__cookies=1597502296408', 33 | 'Host': 'fanyi.youdao.com', 34 | 'Origin': 'http://fanyi.youdao.com', 35 | 'Referer': 'http://fanyi.youdao.com/', 36 | 'user-agent': appVersion, 37 | 'X-Requested-With': 'XMLHttpRequest', 38 | } 39 | 40 | word = content 41 | bv = md5(appVersion.encode()).hexdigest() 42 | lts = str(int(time.time() * 1000)) 43 | salt = lts + str(random.randint(0, 9)) 44 | sign = md5(('fanyideskweb' + word + salt + ']BjuETDhU)zqSxf-=B#7m').encode()).hexdigest() 45 | params = { 46 | 'i': word, 47 | 'from': 'AUTO', 48 | 'to': 'AUTO', 49 | 'smartresult': 'dict', 50 | 'client': 'fanyideskweb', 51 | 'salt': salt, 52 | 'sign': sign, 53 | 'lts': lts, 54 | 'bv': bv, 55 | 'doctype': 'json', 56 | 'version': '2.1', 57 | 'keyfrom': 'fanyi.web', 58 | 'action': 'FY_BY_REALTlME' 59 | } 60 | 61 | response = requests.post(url=url, headers=headers, data=params) 62 | result = response.json() 63 | return {'result': result['translateResult'][0][0]['tgt']} 64 | 65 | 66 | if __name__ == '__main__': 67 | print(translate('Hello World')) 68 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eurkon/api/15c7eb4608f77d3762ed451f92fd716f47f65b9f/favicon.ico -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.26.0 2 | PyExecJS==1.5.1 3 | lxml==4.6.4 4 | uvicorn==0.17.5 5 | Scrapy==2.5.1 6 | fastapi==0.75.0 7 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | VERSION = "1.0.0" 2 | 3 | DEBUG = False 4 | 5 | HTTP_PROXY_URL = "" 6 | 7 | USER_AGENT_LIST = [ 8 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 9 | "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)", 10 | "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)", 11 | "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", 12 | "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)", 13 | "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)", 14 | "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)", 15 | "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)", 16 | "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", 17 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", 18 | "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", 19 | "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5", 20 | "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", 21 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", 22 | "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", 23 | "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52", 24 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11", 25 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER", 26 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)", 27 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)", 28 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER", 29 | "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", 30 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)", 31 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", 32 | "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)", 33 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", 34 | "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", 35 | "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", 36 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", 37 | "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", 38 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre", 39 | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0", 40 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11", 41 | "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10", 42 | ] 43 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "public": true, 4 | "builds": [ 5 | { 6 | "src": "api/main.py", 7 | "use": "@vercel/python", 8 | "config": { 9 | "maxLambdaSize": "15mb", 10 | "runtime": "python3.9" 11 | } 12 | } 13 | ], 14 | "headers": [ 15 | { 16 | "source": "/(.*)", 17 | "headers": [ 18 | { 19 | "key": "Access-Control-Allow-Credentials", 20 | "value": "true" 21 | }, 22 | { 23 | "key": "Access-Control-Allow-Origin", 24 | "value": "*" 25 | }, 26 | { 27 | "key": "Access-Control-Allow-Methods", 28 | "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" 29 | }, 30 | { 31 | "key": "Access-Control-Allow-Headers", 32 | "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" 33 | } 34 | ] 35 | } 36 | ], 37 | "rewrites": [ 38 | { 39 | "source": "/(.*)", 40 | "destination": "api/main.py" 41 | } 42 | ] 43 | } --------------------------------------------------------------------------------