一、瞭解公民第二代身份證組成部分:
前 6 位:對應省自治區直轄市城市的代碼
7--14位:對應出生年月日
15--18位:三位數字順序碼和一位數字校驗碼(順序碼奇數爲男,偶數爲女)
二、實現
個人的實現方法比較笨拙,沒有其他博客中寫的那麼好,我是分開進行得到每個部分,然後最後一起進行組合
Ⅰ、獲取前6位城市區碼,具體數據獲取在最後PS處有詳細代碼
import random, openpyxl, time def get_id_six(data_path): file = openpyxl.load_workbook(data_path) sheet = file.active maxR = sheet.max_row # 獲取最大行 random_int = [random.randint(1, (maxR+1)/2)*2+1 for n in range(1)] # 在規定的範圍內隨機一個奇數 print("得到的隨機數是 %s" % random_int[0]) for i in range(1, maxR+1): if i % 2 == 1 and i == random_int[0]: # 如果i是奇數並且等於隨機的奇數時 id_six = sheet.cell(i, 1).value print("獲得的身份證前6位爲 %s" % id_six) print("獲得的身份證所在地爲 %s" % sheet.cell(i+1, 1).value) return id_six.strip()
PS:從網站爬取下來的數據,因爲能力有限,處理的不夠完整 ,需要自己手動處理數據中開頭的部分和中間部分空行。我自己處理出來的結果是奇數行是城市代碼,偶數行是城市名稱,所以我上面的代碼是取奇數行。(待改進。。。)
Ⅱ、隨機生成合適的出生年月日
def get_birthday(): a1 = (1971, 1, 1, 0, 0, 0, 0, 0, 0) # 設置開始日期時間元組(1950-01-01 00:00:00) a2 = (2002, 12, 31, 23, 59, 59, 0, 0, 0) # 設置結束日期時間元組(2002-12-31 23:59:59) start = time.mktime(a1) # 生成開始時間戳 end = time.mktime(a2) # 生成結束時間戳 # 隨機生成10個日期字符串 for i in range(10): t = random.randint(start, end) # 在開始和結束時間戳中隨機取出一個 date_touple = time.localtime(t) # 將時間戳生成時間元組 date = time.strftime("%Y%m%d", date_touple) # 將時間元組轉成格式化字符串(1976-05-21) # print(date) return date
Ⅲ、得到三位順序碼
def get_three_number(): id = [] for j in range(1, 4): rand_num = random.randint(0, 9) id.append(str(rand_num)) string = ''.join(id) return string
Ⅳ、組合前17位數字
def id_seventeen(data_path): id_seven = [] id_six = get_id_six(data_path) date = get_birthday() three_number = get_three_number() id_seven.append(id_six) id_seven.append(date) id_seven.append(three_number) senventeen = ''.join(id_seven) return senventeen
Ⅴ、得到第18位驗證碼
def jiao_yan_ma(shenfenzheng17): def haoma_validate(shenfenzheng17): if type(shenfenzheng17) in [str, list, tuple]: if len(shenfenzheng17) == 17: return True raise Exception('Wrong argument') if haoma_validate(shenfenzheng17): if type(shenfenzheng17) == str: seq = map(int, shenfenzheng17) elif type(shenfenzheng17) in [list, tuple]: seq = shenfenzheng17 t = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] s = sum(map(lambda x: x[0] * x[1], zip(t, map(int, seq)))) b = s % 11 bd = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'} return bd[b]
Ⅵ、運行最後得到結果
if __name__ == "__main__": id_c = [] senven = id_seventeen("D:/id_six_before.xlsx") jiao_yan = jiao_yan_ma(senven) id_c.append(senven) id_c.append(jiao_yan) id_card = ''.join(id_c) print(id_card)
PS:獲取城市區碼代碼如下:
from urllib import request import re # 使用正則表達式 import openpyxl as openpyxl def getResponse(url): # url請求對象 Request是一個類 url_request = request.Request(url) # print("Request對象的方法是:",url_request.get_method()) # 上下文使用的對象,包含一系列方法 # url_response = request.urlopen(url) #打開一個url或者一個Request對象 url_response = request.urlopen(url_request) ''' geturl():返回 full_url地址 info(): 返回頁面的元(Html的meta標籤)信息 <meta>:可提供有關頁面的元信息(meta-information),比如針對搜索引擎和更新頻度的描述和關鍵詞。 getcode(): 返回響應的HTTP狀態代碼 100-199 用於指定客戶端應相應的某些動作。 200-299 用於表示請求成功。 ------> 200 300-399 用於已經移動的文件並且常被包含在定位頭信息中指定新的地址信息。 400-499 用於指出客戶端的錯誤。 ------> 404 500-599 用於支持服務器錯誤。 read(): 讀取網頁內容,注意解碼方式(避免中文和utf-8之間轉化出現亂碼) ''' return url_response # 返回這個對象 def get_diqu(data): global n # 聲明全局變量n pat = re.compile('>(.*?)<') diqu = pat.findall(data) while '' in diqu: diqu.remove('') file = openpyxl.load_workbook("D:/id_six.xlsx") sheet = file.active for i in range(len(diqu)): print(diqu[i]) sheet["A%d" % (i+1)] = diqu[i] i += 1 file.save("D:/id_six.xlsx") http_response = getResponse("http://www.tcmap.com.cn/list/daima_list.html") # 拿到http請求後的上下文對象(HTTPResponse object) data = http_response.read().decode('gbk') L = get_diqu(data)