├── github ├── README.md ├── requirements.txt ├── __init__.py ├── interview_github.py └── generate_starchart.py ├── mdn_tool ├── README.md ├── requirements.txt ├── __init__.py ├── http_code.py └── status_code.json ├── lottery ├── requirements.txt └── comment_lottery.py ├── README.md ├── LICENSE ├── china_img └── parse_img.py └── .gitignore /github/README.md: -------------------------------------------------------------------------------- 1 | 待补充 -------------------------------------------------------------------------------- /mdn_tool/README.md: -------------------------------------------------------------------------------- 1 | 待补充 -------------------------------------------------------------------------------- /mdn_tool/requirements.txt: -------------------------------------------------------------------------------- 1 | fire -------------------------------------------------------------------------------- /github/requirements.txt: -------------------------------------------------------------------------------- 1 | pygal 2 | requests 3 | -------------------------------------------------------------------------------- /lottery/requirements.txt: -------------------------------------------------------------------------------- 1 | xlrd 2 | pandas 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Script 2 | 基于 python3.7 的 GitHub 的脚本集合 3 | 4 | 详细介绍(待补充) 5 | -------------------------------------------------------------------------------- /github/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | 6 | author: xue.sun 7 | date: 2019/12/31 8 | description: 9 | """ -------------------------------------------------------------------------------- /mdn_tool/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | 6 | author: xue.sun 7 | date: 2019/12/31 8 | description: 9 | """ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0) 2 | 3 | Copyright (c) 2019 HelloGitHub 4 | 5 | ## 您可以自由地: 6 | 共享 — 在任何媒介以任何形式复制、发行本作品 7 | 只要你遵守许可协议条款,许可人就无法收回你的这些权利。 8 | 9 | ## 惟须遵守下列条件: 10 | - 署名 — 您必须给出适当的署名,提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示许可人为您或您的使用背书。 11 | 12 | - 非商业性使用 — 您不得将本作品用于商业目的。 13 | 14 | - 禁止演绎 — 如果您 再混合、转换、或者基于该作品创作,您不可以分发修改作品。 15 | 16 | - 没有附加限制 — 您不得适用法律术语或者 技术措施 从而限制其他人做许可协议允许的事情。 17 | 18 | ## 声明: 19 | 您不必因为公共领域的作品要素而遵守许可协议,或者您的使用被可适用的 例外或限制所允许。 20 | 不提供担保。许可协议可能不会给与您意图使用的所必须的所有许可。例如,其他权利比如形象权、隐私权或人格权可能限制您如何使用作品。 21 | 22 | 更详细的说明:https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode.zh-Hans -------------------------------------------------------------------------------- /github/interview_github.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # 4 | # Author : XueWeiHan 5 | # E-mail : 595666367@qq.com 6 | # Date : 2019-12-28 7 | # Desc : 刷新本机 DNS 加速访问 GitHub 速度、解决图裂的问题 8 | import requests 9 | 10 | 11 | # content = requests.get('https://github.com/521xueweihan/HelloGitHub') 12 | # content 13 | 14 | # import dns.resolver 15 | # 16 | # myResolver = dns.resolver.Resolver() 17 | # myResolver.nameservers = ['180.76.76.76', '223.6.6.6'] 18 | # myAnswers = myResolver.query("github.githubassets.com", "A") 19 | # for rdata in myAnswers: 20 | # print(rdata) 21 | # 22 | import socket 23 | 24 | def getip(): 25 | sock = socket.create_connection(('ns1.dnspod.net', 6666), 20) 26 | ip = sock.recv(16) 27 | sock.close() 28 | return ip 29 | getip() -------------------------------------------------------------------------------- /lottery/comment_lottery.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # 4 | # Author : XueWeiHan 5 | # E-mail : 595666367@qq.com 6 | # Date : 2020-10-16 23:42 7 | # Desc : 微信留言抽奖 8 | import datetime 9 | import random 10 | 11 | import pandas as pd 12 | 13 | print("开始抽奖的时间:{}".format(datetime.datetime.now())) 14 | df = pd.read_excel("/Users/xueweihan/Downloads/HelloGitHub.xlsx") 15 | print("留言总数:{}".format(len(df))) 16 | name_set = set(df["留言者昵称"]) 17 | print("留言总人数:{}".format(len(name_set))) 18 | if "HelloGitHub" in name_set: 19 | name_set.remove("HelloGitHub") 20 | print("参与抽奖人数:{}".format(len(name_set))) 21 | # choices 有放回,sample 无放回 22 | result = random.sample(name_set, 5) 23 | print("中奖用户:{}".format("、".join(result))) 24 | print("结束抽奖时间:{}".format(datetime.datetime.now())) -------------------------------------------------------------------------------- /china_img/parse_img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # 4 | # Author : XueWeiHan 5 | # E-mail : 595666367@qq.com 6 | # Date : 2020-09-29 14:18 7 | # Desc : 8 | import os 9 | import time 10 | import re 11 | import requests 12 | flag_url = "gif" 13 | data_file = "vx.txt" 14 | save_pic_dir = "/Users/xueweihan/Desktop/pic/" 15 | 16 | 17 | def parse_img(): 18 | # 正则表达式 19 | pattern = re.compile(r'https://mmbiz[^\s]*"') 20 | with open(data_file, "r") as fb: 21 | year = 2020 22 | # 提取图片 23 | urls = pattern.findall(fb.read()) 24 | for url in urls: 25 | if flag_url in url: 26 | year = year - 1 27 | continue 28 | file_name = "{}.png".format(year) 29 | 30 | if os.path.exists(save_pic_dir+file_name): 31 | file_name = "{}_{}.png".format(year, int(time.time())) 32 | download(file_name, url) 33 | time.sleep(0.3) 34 | print("download {} picture.".format(len(urls))) 35 | 36 | 37 | def download(file_name, url): 38 | rs = requests.get(url) 39 | if rs.status_code == 200: 40 | with open(save_pic_dir + file_name, 'wb+') as f: 41 | for chunk in rs: 42 | f.write(chunk) 43 | print('download {} finish'.format(file_name)) 44 | else: 45 | print("download: name: {} url:{}, status_code:{} error", file_name, url, 46 | requests.status_codes) 47 | 48 | 49 | if __name__ == '__main__': 50 | parse_img() 51 | 52 | -------------------------------------------------------------------------------- /mdn_tool/http_code.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # 4 | # Author : XueWeiHan 5 | # E-mail : 595666367@qq.com 6 | # Date : 2019-12-31 7 | # Desc : 查询 HTTP code 解释 8 | import json 9 | import textwrap 10 | 11 | import fire 12 | 13 | 14 | def read_file(file_name): 15 | with open(file_name, 'r', encoding='utf-8') as fb: 16 | file_data = fb.read() 17 | status_code_data = json.loads(file_data) 18 | return status_code_data 19 | 20 | 21 | STATUS_CODE = read_file('status_code.json') 22 | STATUS_CODE_TEMPLATE = """ 23 | \x1b[1m\x1b[36m{code} {info}\x1b[0m\x1b[0m 24 | \x1b[32m{desc}\x1b[0m 25 | """[1:] 26 | 27 | 28 | class StatusCode(object): 29 | def __init__(self, code=0, info=''): 30 | self.code = str(code) 31 | self.info = info.upper() 32 | 33 | def message(self): 34 | info_list = STATUS_CODE.values() 35 | for info_item in info_list: 36 | data_list = info_item['item_list'] 37 | for fi_data in data_list: 38 | desc = fi_data['description'] 39 | desc = textwrap.fill(desc, 30) 40 | if self.code == fi_data['number'] or self.info == fi_data[ 41 | 'info']: 42 | result = STATUS_CODE_TEMPLATE.format( 43 | code=fi_data['number'], info=fi_data['info'], 44 | desc=desc) 45 | return result 46 | 47 | else: 48 | return '\x1b[31m未查到 {} 对应信息。\x1b[0m'.format(self.code) 49 | 50 | 51 | if __name__ == '__main__': 52 | fire.Fire(StatusCode) 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | .DS_Store 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # Environments 86 | .env 87 | .venv 88 | env/ 89 | venv/ 90 | ENV/ 91 | env.bak/ 92 | venv.bak/ 93 | 94 | # Spyder project settings 95 | .spyderproject 96 | .spyproject 97 | 98 | # Rope project settings 99 | .ropeproject 100 | 101 | # mkdocs documentation 102 | /site 103 | 104 | # mypy 105 | .mypy_cache/ 106 | 107 | # idea 108 | .idea/ -------------------------------------------------------------------------------- /github/generate_starchart.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # 4 | # Author : XueWeiHan 5 | # E-mail : 595666367@qq.com 6 | # Date : 2019-09-18 22:45 7 | # Desc : 生成星图脚本 8 | import time 9 | import datetime 10 | from collections import OrderedDict 11 | 12 | import pygal 13 | from pygal.style import Style 14 | import requests 15 | 16 | 17 | class GitHubRepositories(object): 18 | def __init__(self, name, token, per_page=100, max_star_limit=10000, 19 | min_star_limit=10, create_days_limit=10, mode='count', 20 | time_node_count=1): 21 | self.name = name 22 | self.token = token 23 | self.limit_remaining = 0 24 | self.reset_limit_time = None 25 | self.per_page = per_page 26 | self.info = None 27 | self.stargazers = set() 28 | self.max_star_limit = max_star_limit 29 | self.min_star_limit = min_star_limit 30 | self.create_days_limit = create_days_limit 31 | self.star_map = OrderedDict() 32 | self.days_count = None 33 | self.mode = mode # 展示star总和('count'), 还是star的增量('change') 34 | self.time_node_count = time_node_count 35 | self.x_node_list = None # x轴为时间 36 | self.y_node_list = None # y轴为数量 37 | # 默认为当前时间 38 | self.max_date_str = datetime.datetime.now().strftime('%Y-%m-%d') 39 | # 项目创建时间 40 | self.min_date_str = None 41 | # 停止请求数据 42 | self.end_request = False 43 | self.interval_days = None # 显示x轴的时间两个点应相隔几天 44 | 45 | @property 46 | def headers(self): 47 | # token 授权 48 | return { 49 | 'Authorization': 'token {}'.format(self.token) 50 | } 51 | 52 | @staticmethod 53 | def fix_time(time_str, rtype='time'): 54 | # github 返回的时间是 ISO 8601 规则的时间(0时区),下面转化成北京时间(+8时区) 55 | epoch_time = datetime.datetime.strptime(time_str, 56 | '%Y-%m-%dT%H:%M:%SZ') 57 | epoch_time = epoch_time + datetime.timedelta(hours=8) 58 | if rtype == 'time': 59 | epoch_time_str = epoch_time.date().strftime('%Y-%m-%d %H:%M:%S') 60 | else: 61 | epoch_time_str = epoch_time.date().strftime('%Y-%m-%d') 62 | return epoch_time_str 63 | 64 | def get_repo_info(self): 65 | url = 'https://api.github.com/repos/{}'.format(self.name) 66 | response = requests.get(url, headers=self.headers) 67 | if response.status_code == 200: 68 | self.limit_remaining = int(response.headers['X-RateLimit-Remaining']) 69 | self.reset_limit_time = datetime.datetime.fromtimestamp( 70 | int(response.headers['X-RateLimit-Reset'])).strftime( 71 | "%Y-%m-%d %H:%M:%S") 72 | self.info = response.json() 73 | # 项目名字标准化 74 | self.name = self.info['full_name'] 75 | # 把info中的时间转化成北京时间 76 | self.min_date_str = self.fix_time(self.info['created_at'], 77 | rtype='date') 78 | self.info['created_at'] = self.fix_time(self.info['created_at']) 79 | self.info['updated_at'] = self.fix_time(self.info['updated_at']) 80 | self.info['pushed_at'] = self.fix_time(self.info['pushed_at']) 81 | 82 | def generate_all_stargazers_urls(self): 83 | """ 84 | 请求所有的 stargazers api url 85 | """ 86 | all_stargazers_urls = [] 87 | stargazers_count = self.info['stargazers_count'] 88 | stargazers_url_format = 'https://api.github.com/repos/{}/stargazers?' \ 89 | 'page={}&per_page={}' 90 | page_count = int(stargazers_count / self.per_page) + 1 91 | for i in range(1, page_count + 1): 92 | all_stargazers_urls.append(stargazers_url_format.format( 93 | self.name, i, self.per_page)) 94 | return all_stargazers_urls 95 | 96 | def parse_stargazers_data(self, stargazers_data): 97 | for fi_data in stargazers_data: 98 | # 根据 star 时间数据聚合到天 99 | epoch_date_str = self.fix_time(fi_data['starred_at'], 'date') 100 | epoch_date = datetime.datetime.strptime(epoch_date_str, '%Y-%m-%d') 101 | max_date = datetime.datetime.strptime(self.max_date_str, '%Y-%m-%d') 102 | if epoch_date > max_date: 103 | self.end_request = True 104 | break 105 | self.stargazers.add(fi_data['user']['id']) 106 | if epoch_date_str in self.star_map: 107 | self.star_map[epoch_date_str] += 1 108 | else: 109 | self.star_map[epoch_date_str] = 1 110 | 111 | def get_stargazer(self, req_s, url, headers): 112 | rs = req_s.get(url, headers=headers) 113 | self.parse_stargazers_data(rs.json()) 114 | 115 | def get_all_stargazers(self): 116 | """ 117 | 请求所有的 stargazers api url 118 | """ 119 | all_stargazers_urls = self.generate_all_stargazers_urls() 120 | if self.limit_remaining < len(all_stargazers_urls): 121 | msg = '当前时次请求数量超出' 122 | print(msg) 123 | raise Exception(msg) 124 | else: 125 | self.limit_remaining -= len(all_stargazers_urls) 126 | headers = self.headers 127 | headers['Accept'] = 'application/vnd.github.v3.star+json' 128 | s = requests.session() 129 | for stargazers_url in all_stargazers_urls: 130 | if not self.end_request: 131 | print(stargazers_url, self.end_request) 132 | self.get_stargazer(s, stargazers_url, headers) 133 | # lock = threading.Lock() 134 | # threads = [threading.Thread(target=self.get_stargazer, 135 | # args=(s, stargazers_url, headers, lock)) 136 | # for stargazers_url in all_stargazers_urls] 137 | # [thread.start() for thread in threads] 138 | # [thread.join() for thread in threads] 139 | # del s 140 | print('request limit remaining: {}'.format(self.limit_remaining)) 141 | 142 | def make_time_node(self): 143 | max_date = datetime.datetime.strptime(self.max_date_str, '%Y-%m-%d') 144 | min_date = datetime.datetime.strptime(self.min_date_str, '%Y-%m-%d') 145 | date_list = [self.min_date_str] 146 | self.days_count = (max_date - min_date).days # 该项目共创建了多少天 147 | self.interval_days = self.days_count / self.time_node_count 148 | flag_date = max_date - datetime.timedelta(days=self.interval_days) 149 | tmp_date = min_date 150 | # 生成所有的 x_node(时间节点) 151 | while tmp_date < flag_date: 152 | date_node = tmp_date + datetime.timedelta(days=self.interval_days) 153 | tmp_date = date_node 154 | date_list.append(date_node.strftime('%Y-%m-%d')) 155 | date_list.append(self.max_date_str) 156 | self.x_node_list = date_list 157 | 158 | def make_value_node(self): 159 | min_date = datetime.datetime.strptime(self.min_date_str, '%Y-%m-%d') 160 | # 初始化结果dict,防止某段时间的数为空造成异常 161 | result_data = {date_node: 0 for date_node in self.x_node_list} 162 | for k, v in self.star_map.items(): 163 | starred_datetime = datetime.datetime.strptime(k, '%Y-%m-%d') 164 | # 把原始数据的日期对应到node轴,并把value累加(原始数据聚合到x轴的量级) 165 | date_index = int((starred_datetime - min_date).days / self.interval_days) 166 | if (starred_datetime - min_date).days % self.interval_days: 167 | date_index += 1 168 | result_k = self.x_node_list[date_index] 169 | result_data[result_k] += v 170 | 171 | if self.mode == 'count': 172 | # 某x轴上日期时的star总数 173 | for index, x_node in enumerate(self.x_node_list): 174 | if index != 0: 175 | result_data[x_node] += result_data[ 176 | self.x_node_list[index - 1]] 177 | 178 | self.y_node_list = [result_data[fi_x_node] for fi_x_node in 179 | self.x_node_list] 180 | 181 | def init(self): 182 | start_time = time.time() 183 | self.get_repo_info() 184 | error_msg = '项目名称:{},生成失败原因:'.format(self.name) 185 | if self.info: 186 | created_datetime = datetime.datetime.strptime( 187 | self.info['created_at'], '%Y-%m-%d %H:%M:%S') 188 | created_days = (datetime.datetime.now() - created_datetime).days 189 | if created_days < self.create_days_limit: 190 | error_msg += '不支持创建天数小于 {} 天的项目'.format(self.create_days_limit) 191 | raise Exception(error_msg) 192 | elif self.info['stargazers_count'] > self.max_star_limit: 193 | error_msg += '暂不支持 star 数量大于 {} 的项目'.format(self.max_star_limit) 194 | raise Exception(error_msg) 195 | elif self.info['stargazers_count'] < self.min_star_limit: 196 | error_msg += '暂不支持 star 数量小于 {} 的项目'.format(self.min_star_limit) 197 | raise Exception(error_msg) 198 | elif not self.limit_remaining: 199 | error_msg += '(测试阶段)请求数达到限制次数' 200 | raise Exception(error_msg) 201 | else: 202 | try: 203 | self.get_all_stargazers() 204 | self.make_time_node() 205 | self.make_value_node() 206 | except Exception as e: 207 | raise e 208 | else: 209 | error_msg += '未找到项目' 210 | raise Exception(error_msg) 211 | print('Get {} data speed time: {}'.format( 212 | self.name, time.time() - start_time)) 213 | 214 | 215 | class GenerateStarSVG(object): 216 | @staticmethod 217 | def make_svg(svg_type, x_nodes, y_nodes): 218 | # 参数分别修改:x轴描述旋转角度、圆角、颜色(Python 蓝) 219 | line_chart = pygal.Line(x_label_rotation=20, tooltip_border_radius=10, 220 | background='transparent', 221 | plot_background='transparent', 222 | style=Style(colors=('#376fa0',))) 223 | line_chart.x_labels = x_nodes 224 | line_chart.add("Star", y_nodes) 225 | if svg_type == 'uri': 226 | return line_chart.render_data_uri() 227 | elif svg_type == 'svg': 228 | line_chart.render_to_file('local.svg') 229 | 230 | 231 | def main(config, repo_name='521xueweihan/HelloGitHub'): 232 | _g = GitHubRepositories(repo_name, config['token'], 233 | per_page=config['per_page'], 234 | max_star_limit=config['max_star_limit'], 235 | min_star_limit=config['min_star_limit'], 236 | create_days_limit=config['create_days_limit']) 237 | _g.init() 238 | starchart = { 239 | 'repo_name': _g.info['full_name'], 240 | 'repo_url': _g.info['html_url'], 241 | 'repo_created_at': _g.info['created_at'], 242 | 'days_count': _g.days_count, 243 | 'star_count': len(_g.stargazers), 244 | 'y_nodes': _g.y_node_list, 245 | 'x_nodes': _g.x_node_list, 246 | 'create_time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 247 | } 248 | return starchart 249 | 250 | 251 | if __name__ == '__main__': 252 | config = { 253 | 'token': 'xxxx', 254 | 'per_page': 100, 255 | 'max_star_limit': 200000, 256 | 'min_star_limit': 10, 257 | 'create_days_limit': 10, 258 | } 259 | g = GitHubRepositories('username/project_name', config['token'], 260 | per_page=config['per_page'], 261 | max_star_limit=config['max_star_limit'], 262 | min_star_limit=config['min_star_limit'], 263 | create_days_limit=config['create_days_limit']) 264 | g.init() 265 | svg = GenerateStarSVG() 266 | svg.make_svg('svg', g.x_node_list, g.y_node_list) 267 | 268 | -------------------------------------------------------------------------------- /mdn_tool/status_code.json: -------------------------------------------------------------------------------- 1 | { 2 | "100": { 3 | "message": "信息响应", 4 | "item_list" : [ 5 | { 6 | "number": "100", 7 | "info": "Continue", 8 | "description": "这个临时响应表明,迄今为止的所有内容都是可行的,客户端应该继续请求,如果已经完成,则忽略它。" 9 | }, 10 | { 11 | "number": "101", 12 | "info": "Switching Protocol", 13 | "description": "该代码是响应客户端的 Upgrade 标头发送的,并且指示服务器也正在切换的协议。" 14 | }, 15 | { 16 | "number": "102", 17 | "info": "Processing", 18 | "description": "此代码表示服务器已收到并正在处理该请求,但没有响应可用。" 19 | }, 20 | { 21 | "number": "103", 22 | "info": "Early Hints", 23 | "description": "此状态代码主要用于与 Link 链接头一起使用,以允许用户代理在服务器仍在准备响应时开始预加载资源。" 24 | } 25 | ]}, 26 | "200": { 27 | "message": "成功响应", 28 | "item_list": [ 29 | { 30 | "number": "200", 31 | "info": "OK", 32 | "description": "请求成功。成功的含义取决于 HTTP 方法:\nGET:资源已被提取并在消息正文中传输。\nHEAD:实体标头位于消息正文中。\nPOST:描述动作结果的资源在消息体中传输。\nTRACE:消息正文包含服务器收到的请求消息。" 33 | }, 34 | { 35 | "number": "201", 36 | "info": "Created", 37 | "description": "该请求已成功,并因此创建了一个新的资源。这通常是在POST请求,或是某些 PUT 请求之后返回的响应。" 38 | }, 39 | { 40 | "number": "202", 41 | "info": "Accepted", 42 | "description": "请求已经接收到,但还未响应,没有结果。意味着不会有一个异步的响应去表明当前请求的结果,预期另外的进程和服务去处理请求,或者批处理。" 43 | }, 44 | { 45 | "number": "203", 46 | "info": "Non-Authoritative Information", 47 | "description": "服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如,包含资源的元数据可能导致原始服务器知道元信息的超集。使用此状态码不是必须的,而且只有在响应不使用此状态码便会返回 200 OK 的情况下才是合适的。" 48 | }, 49 | { 50 | "number": "204", 51 | "info": "No Content", 52 | "description": "服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。由于 204 响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。" 53 | }, 54 | { 55 | "number": "205", 56 | "info": "Reset Content", 57 | "description": "服务器成功处理了请求,且没有返回任何内容。但是与 204 响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。与 204 响应一样,该响应也被禁止包含任何消息体,且以消息头后的第一个空行结束。" 58 | }, 59 | { 60 | "number": "206", 61 | "info": "Partial Content", 62 | "description": "服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。" 63 | }, 64 | { 65 | "number": "207", 66 | "info": "Multi-Status", 67 | "description": "由 WebDAV(RFC 2518) 扩展的状态码,代表之后的消息体将是一个 XML 消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。" 68 | }, 69 | { 70 | "number": "208", 71 | "info": "Multi-Status", 72 | "description": "在 DAV 里面使用:propstat 响应元素以避免重复枚举多个绑定的内部成员到同一个集合。" 73 | }, 74 | { 75 | "number": "226", 76 | "info": "IM Used", 77 | "description": "服务器已经完成了对资源的 GET 请求,并且响应是对当前实例应用的一个或多个实例操作结果的表示。" 78 | } 79 | ] 80 | }, 81 | "300": { 82 | "message": "重定向", 83 | "item_list": [ 84 | { 85 | "number": "300", 86 | "info": "Multiple Choice", 87 | "description": "被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。" 88 | }, 89 | { 90 | "number": "301", 91 | "info": "Moved Permanently", 92 | "description": "被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。" 93 | }, 94 | { 95 | "number": "302", 96 | "info": "Found", 97 | "description": "请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在 Cache-Control 或 Expires 中进行了指定的情况下,这个响应才是可缓存的。" 98 | }, 99 | { 100 | "number": "303", 101 | "info": "See Other", 102 | "description": "对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。" 103 | }, 104 | { 105 | "number": "304", 106 | "info": "Not Modified", 107 | "description": "如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304 响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。" 108 | }, 109 | { 110 | "number": "305", 111 | "info": "Use Proxy", 112 | "description": "被请求的资源必须通过指定的代理才能被访问。Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立 305 响应。" 113 | }, 114 | { 115 | "number": "306", 116 | "info": "unused", 117 | "description": "在最新版的规范中,306 状态码已经不再被使用。" 118 | }, 119 | { 120 | "number": "307", 121 | "info": "Temporary Redirect", 122 | "description": "请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在 Cache-Control 或 Expires 中进行了指定的情况下,这个响应才是可缓存的。" 123 | }, 124 | { 125 | "number": "308", 126 | "info": "Permanent Redirect", 127 | "description": "这意味着资源现在永久位于由 Location: HTTP Response 标头指定的另一个 URI。 这与 301 Moved Permanently HTTP 响应代码具有相同的语义,但用户代理不能更改所使用的 HTTP 方法:如果在第一个请求中使用 POST,则必须在第二个请求中使用 POST。" 128 | } 129 | ] 130 | }, 131 | "400": { 132 | "message": "客户端响应", 133 | "item_list": [ 134 | { 135 | "number": "400", 136 | "info": "Bad Request", 137 | "description": "1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。\n2、请求参数有误。" 138 | }, 139 | { 140 | "number": "401", 141 | "info": "Unauthorized", 142 | "description": "当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。" 143 | }, 144 | { 145 | "number": "402", 146 | "info": "Payment Required", 147 | "description": "此响应码保留以便将来使用,创造此响应码的最初目的是用于数字支付系统,然而现在并未使用。" 148 | }, 149 | { 150 | "number": "403", 151 | "info": "Forbidden", 152 | "description": "服务器已经理解请求,但是拒绝执行它。与 401 响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个 404 响应,假如它不希望让客户端获得任何信息。" 153 | }, 154 | { 155 | "number": "404", 156 | "info": "Not Found", 157 | "description": "请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404 这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。" 158 | }, 159 | { 160 | "number": "405", 161 | "info": "Method Not Allowed", 162 | "description": "请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个 Allow 头信息用以表示出当前资源能够接受的请求方法的列表。 鉴于 PUT、DELETE 方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回 405 错误。" 163 | }, 164 | { 165 | "number": "406", 166 | "info": "Not Acceptable", 167 | "description": "请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。" 168 | }, 169 | { 170 | "number": "407", 171 | "info": "Proxy Authentication Required", 172 | "description": "与 401 响应类似,只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问。客户端可以返回一个 Proxy-Authorization 信息头用以验证。" 173 | }, 174 | { 175 | "number": "408", 176 | "info": "Request Timeout", 177 | "description": "请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。" 178 | }, 179 | { 180 | "number": "409", 181 | "info": "Conflict", 182 | "description": "由于和被请求的资源的当前状态之间存在冲突,请求无法完成。这个代码只允许用在这样的情况下才能被使用:用户被认为能够解决冲突,并且会重新提交新的请求。该响应应当包含足够的信息以便用户发现冲突的源头。" 183 | }, 184 | { 185 | "number": "410", 186 | "info": "Gone", 187 | "description": "被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。这样的状况应当被认为是永久性的。如果可能,拥有链接编辑功能的客户端应当在获得用户许可后删除所有指向这个地址的引用。如果服务器不知道或者无法确定这个状况是否是永久的,那么就应该使用 404 状态码。除非额外说明,否则这个响应是可缓存的。" 188 | }, 189 | { 190 | "number": "411", 191 | "info": "Length Required", 192 | "description": "服务器拒绝在没有定义 Content-Length 头的情况下接受请求。在添加了表明请求消息体长度的有效 Content-Length 头之后,客户端可以再次提交该请求。" 193 | }, 194 | { 195 | "number": "412", 196 | "info": "Precondition Failed", 197 | "description": "服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。" 198 | }, 199 | { 200 | "number": "413", 201 | "info": "Payload Too Large", 202 | "description": "服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。如果这个状况是临时的,服务器应当返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试。" 203 | }, 204 | { 205 | "number": "414", 206 | "info": "URI Too Long", 207 | "description": "请求的URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。这比较少见,通常的情况包括:本应使用POST方法的表单提交变成了 GET 方法,导致查询字符串(Query String)过长。" 208 | }, 209 | { 210 | "number": "415", 211 | "info": "Unsupported Media Type", 212 | "description": "对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。" 213 | }, 214 | { 215 | "number": "416", 216 | "info": "Requested Range Not Satisfiable", 217 | "description": "如果请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头,那么服务器就应当返回 416 状态码。" 218 | }, 219 | { 220 | "number": "417", 221 | "info": "Expectation Failed", 222 | "description": "此响应代码意味着服务器无法满足 Expect 请求标头字段指示的期望值。" 223 | }, 224 | { 225 | "number": "418", 226 | "info": "I'm a teapot", 227 | "description": "服务器拒绝尝试用 “茶壶冲泡咖啡”。" 228 | }, 229 | { 230 | "number": "421", 231 | "info": "Misdirected Request", 232 | "description": "该请求针对的是无法产生响应的服务器。 这可以由服务器发送,该服务器未配置为针对包含在请求 URI 中的方案和权限的组合产生响应。" 233 | }, 234 | { 235 | "number": "422", 236 | "info": "Unprocessable Entity", 237 | "description": "请求格式良好,但由于语义错误而无法遵循。" 238 | }, 239 | { 240 | "number": "423", 241 | "info": "Locked", 242 | "description": "正在访问的资源被锁定。" 243 | }, 244 | { 245 | "number": "424", 246 | "info": "Failed Dependency", 247 | "description": "由于先前的请求失败,所以此次请求失败。" 248 | }, 249 | { 250 | "number": "425", 251 | "info": "Too Early", 252 | "description": "服务器不愿意冒着风险去处理可能重播的请求。" 253 | }, 254 | { 255 | "number": "426", 256 | "info": "Upgrade Required", 257 | "description": "服务器拒绝使用当前协议执行请求,但可能在客户机升级到其他协议后愿意这样做。 服务器在 426 响应中发送 Upgrade 头以指示所需的协议。" 258 | }, 259 | { 260 | "number": "428", 261 | "info": "Precondition Required", 262 | "description": "原始服务器要求该请求是有条件的。 旨在防止“丢失更新”问题,即客户端获取资源状态,修改该状态并将其返回服务器,同时第三方修改服务器上的状态,从而导致冲突。" 263 | }, 264 | { 265 | "number": "429", 266 | "info": "Too Many Requests", 267 | "description": "用户在给定的时间内发送了太多请求(“限制请求速率”)。" 268 | }, 269 | { 270 | "number": "431", 271 | "info": "Request Header Fields Too Large", 272 | "description": "服务器不愿意处理请求,因为它的 请求头字段太大(Request Header Fields Too Large)。 请求可以在减小请求头字段的大小后重新提交。" 273 | }, 274 | { 275 | "number": "451", 276 | "info": "Unavailable For Legal Reasons", 277 | "description": "用户请求非法资源,例如:由政府审查的网页。" 278 | } 279 | ] 280 | }, 281 | "500": { 282 | "message": "服务端响应", 283 | "item_list": [ 284 | { 285 | "number": "500", 286 | "info": "Internal Server Error", 287 | "description": "服务器遇到了不知道如何处理的情况。" 288 | }, 289 | { 290 | "number": "501", 291 | "info": "Not Implemented", 292 | "description": "此请求方法不被服务器支持且无法被处理。只有 GET 和 HEAD 是要求服务器支持的,它们必定不会返回此错误代码。" 293 | }, 294 | { 295 | "number": "502", 296 | "info": "Bad Gateway", 297 | "description": "此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。" 298 | }, 299 | { 300 | "number": "503", 301 | "info": "Service Unavailable", 302 | "description": "服务器没有准备好处理请求。 常见原因是服务器因维护或重载而停机。 请注意,与此响应一起,应发送解释问题的用户友好页面。 这个响应应该用于临时条件和 Retry-After:如果可能的话,HTTP头应该包含恢复服务之前的估计时间。 网站管理员还必须注意与此响应一起发送的与缓存相关的标头,因为这些临时条件响应通常不应被缓存。" 303 | }, 304 | { 305 | "number": "504", 306 | "info": "Gateway Timeout", 307 | "description": "当服务器作为网关,不能及时得到响应时返回此错误代码。" 308 | }, 309 | { 310 | "number": "505", 311 | "info": "HTTP Version Not Supported", 312 | "description": "服务器不支持请求中所使用的 HTTP 协议版本。" 313 | }, 314 | { 315 | "number": "506", 316 | "info": "Variant Also Negotiates", 317 | "description": "服务器有一个内部配置错误:对请求的透明内容协商导致循环引用。" 318 | }, 319 | { 320 | "number": "507", 321 | "info": "Insufficient Storage", 322 | "description": "服务器有内部配置错误:所选的变体资源被配置为参与透明内容协商本身,因此不是协商过程中的适当端点。" 323 | }, 324 | { 325 | "number": "508", 326 | "info": "Loop Detected", 327 | "description": "服务器在处理请求时检测到无限循环。" 328 | }, 329 | { 330 | "number": "510", 331 | "info": "Not Extended", 332 | "description": "客户端需要对请求进一步扩展,服务器才能实现它。服务器会回复客户端发出扩展请求所需的所有信息。" 333 | }, 334 | { 335 | "number": "511", 336 | "info": "Network Authentication Required", 337 | "description": "511 状态码指示客户端需要进行身份验证才能获得网络访问权限。" 338 | } 339 | ] 340 | } 341 | } --------------------------------------------------------------------------------