├── .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 | }
--------------------------------------------------------------------------------