# – coding: gbk –
# -- coding: utf-8 --
import web
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs
import datetime


def calculate_check_digit(id_number):
    if len(id_number) != 17:
        return None

    weight = [int(num) for num in '798621345']
    sum = 0
    for i in range(17):
        sum += int(id_number[i]) * weight[i]
    check_digit = (12 - (sum % 11)) % 11
    return str(check_digit) if check_digit < 10 else 'X'


def upgrade_id_number(id_number):
    if len(id_number) != 15:
        return None

    id_number = id_number[:6] + '19' + id_number[6:]
    check_digit = calculate_check_digit(id_number)
    return id_number + check_digit


def validate_id_number(id_number):
    if len(id_number) == 18:
        check_digit = calculate_check_digit(id_number[:17])
        if check_digit != id_number[-1]:
            return False
    elif len(id_number) == 15:
        upgraded_id_number = upgrade_id_number(id_number)
        if upgraded_id_number:
            return validate_id_number(upgraded_id_number)
        else:
            return False
    else:
        return False

    birth_date = id_number[6:14]
    try:
        year = int(birth_date[:4])
        month = int(birth_date[4:6])
        day = int(birth_date[6:8])
        datetime.datetime(year, month, day)
    except ValueError:
        return False
    
    return True


def get_gender(id_number):
    if len(id_number) == 18:
        gender_digit = int(id_number[-2])
    elif len(id_number) == 15:
        gender_digit = int(id_number[-1])
    else:
        return None

    if gender_digit % 2 == 0:
        return '女性'
    else:
        return '男性'


def get_birthplace(id_number):
    provinces = {
        '11': '北京',
        '12': '天津',
        '13': '河北',
        '14': '山西',
        '15': '内蒙古',
        '21':' 辽宁',
        '22': '吉林',
        '23': '黑龙江',
        '31': '上海',
        '32': '江苏',
        '33': '浙江',
        '34':' 安徽',
        '35': '福建',
        '36': '江西',
        '37': '山东',
        '41': '河南',
        '42': '湖北',
        '43': '湖南',
        '44': '广东',
        '45': '广西',
        '46': '海南',
        '50': '重庆',
        '51': '四川',
        '52': '贵州',
        '53': '云南',
        '54': '西藏',
        '61': '陕西',
        '62': '甘肃',
        '63': '青海',
        '64': '宁夏',
        '65': '新疆',
        '71': '台湾',
        '81': '香港',
        '82': '澳门',
        '91': '国外'
    }
    province_code = id_number[:2]
    return provinces.get(province_code)
 
urls = ( '/', 'IndexHandler','/check', 'CheckHandler',)



class MyHTTPRequestHandler(BaseHTTPRequestHandler):


    class IndexHandler:
        def do_GET(self):
            if self.path == '/':
                self.send_response(200)
                self.send_header('Content-Type', 'text/html')
                self.end_headers()
                self.wfile.write(('''
                    <!DOCTYPE html>
                    <html>
                        <head>
                            <meta charset="UTF-8">
                            <title>身份证号码校验系统</title>
                        </head>
                        <body>
                            <h1>身份证号码校验系统</h1>
                            <form method="POST" action="/check">
                                <label for="idcard">请输入身份证号码：</label>
                                <input type="text" id="idcard" name="idcard" required>
                                <input type="submit" value="校验">
                            </form>
                        </body>
                    </html>''').encode('utf-8'))

    class CheckHandler:
        def do_POST(self):
            if self.path == '/check':
                content_len = int(self.headers.get('Content-Length', 0))
                post_body = self.rfile.read(content_len).decode()
                data = parse_qs(post_body)
                id_number = data.get('idcard', [''])[0]

                if validate_id_number(id_number):
                    result = '有效'
                    gender = get_gender(id_number)
                    birthplace = get_birthplace(id_number)
                    result += f'<br>性别：{gender}' if gender else ''
                    result += f'<br>出生地：{birthplace}' if birthplace else ''
                else:
                    result = '无效'

                self.send_response(200)
                self.send_header('Content-Type', 'text/html')
                self.end_headers()
                self.wfile.write(('''
                    <!DOCTYPE html>
                    <html>
                        <head>
                            <meta charset=“UTF-8”>
                        </head>
                        <body>
                            结果: 
                ''' + str(result) + '</body></html>').encode('utf-8'))


def run(server_class=HTTPServer, handler_class=MyHTTPRequestHandler, port=8000):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print(f'Starting server on port {port}…')
    httpd.serve_forever()


if __name__ == "__main__":
        app = web.application(urls, globals())
        web.httpserver.runsimple(app.wsgifunc(), ("127.0.0.1", 8000))

运行后，网页出现

<class 'KeyError'> at /
'IndexHandler'