阅读本文大概需要 5 分钟。
三叔为人爽快,对朋友那是真讲义气,关系铁的借钱不用借条,不铁的写个借条就行,就是这么豪爽的老实人,现在却遇到了老赖,当初承诺还钱的「朋友」却玩起了失踪,电话不接,消息不回。三叔也急需用钱,就拿着借条去法院起诉,但是法院需要提供身份证号,但借条是只有名字,当时并未留身份证号。于是三叔找我帮忙,希望我能帮助查出此人的身份证号。提供的信息很有限,就姓名、手机号、所在城市。
我开始了头脑风暴,他是否开通某银行的银行卡,让银行的朋友帮忙查,或者让手机号所在的电信公司的朋友帮忙查,或者让派出所工作的朋友帮助查,然后这些方法都否定了,一是我没有这些行业上班的朋友,二是就算有,他们也极大可能没有查询权限,即使有权限,他们也不可能冒风险帮我查,毕竟这是涉及用户隐私的事情。
借钱不还,这不是老赖么?对付老赖,我想到了网上的公开信息。于是我去中国裁判文书网查了下,看看有没有他的相关文书:http://wenshu.court.gov.cn/,输入姓名一搜,果然有:
选择就近的法院点开一看,有详细信息,还是 2016 年的,如果三叔当年上网查下这个人,也许就不会借钱给他了:
这些信息跟三叔确认后,就是这个乔二胡,于是得到其出生日期、省市县信息。根据身份证编码规则,前 6 位地区码已经确认为 412826,如果地区码有更新,年纪大的应该按老编码来,这里的汝南县最新的编码是 411727。中间的生日也确认下来 19610420,身份证共 18 位,还有 4 位待确定。最后一个是校验位,倒数第二位是性别位,奇数为男,偶数为女,还有两位是顺序号,从 00 到 99,由于乔二胡是男性,因此身份证范围限定在 500 以内。这 500 个身份证号使用程序可以很容易计算出来,比如使用下面的代码就可以:
生成身份下号程序代码:
代码语言:javascript复制# -*- coding: utf-8 -*-
class IdNumber(str):
def __init__(self, id_number):
super(IdNumber, self).__init__()
self.id = id_number
def get_check_digit(self):
"""通过身份证号获取校验码"""
check_sum = 0
for i in range(0, 17):
check_sum = ((1 << (17 - i)) % 11) * int(self.id[i])
check_digit = (12 - (check_sum % 11)) % 11
return check_digit if check_digit < 10 else "X"
@classmethod
def generate_myid(cls):
generate_ids = []
# 随机生成一个区域码(6位数)
area_code = "412826"
# 限定出生日期范围(8位数)
birth_day = "19610420"
# 顺序码(2位数)
for i in range(100):
sort_no = f"{i:02d}"
for j in [x for x in range(10) if x % 2 != 0]:
sex = j
prefix = f"{area_code}{birth_day}{sort_no}{sex}"
valid_bit = str(cls(prefix).get_check_digit())
generate_ids.append(f"{prefix}{valid_bit}")
return generate_ids
if __name__ == "__main__":
generate_ids = IdNumber.generate_myid()
print(len(generate_ids))
for id in generate_ids:
print(id)
问题是怎么从这 500 个身份证号中找出哪个是乔二胡的。我又想到了老赖,他有 6 个裁判文书,有的强制执行都没用(借钱一定要有要不回来的心理准备),所以,他必然是一个失信被执行人。打开中国执行信息公开网 http://zxgk.court.gov.cn/。
点击综合查询试一试:
这是个非常好用的接口,如果知道了一个人的身份证号,可以查看其公开的执行信息来确定他是不是老赖;如果确定是老赖,那么可以输入身份证号看身份证号是否正确,如果正确就会显示结果,如果不正确就如上图所示没有找到相关结果。
按顺序将这 500 个身份证号逐一查询,如果查询到结果就说明该身份证号已找到。问题是这个有验证码的网站,手工查询一次至少需要约 30 秒,最坏情况查询 500 次,约 4 小时,这明显太久了,这不是我要的结果,还好人生苦短,我用 Python 。
爬虫写起来并不复杂,但这里要解决的稍复杂些的是验证码,好在我善于发现别人已经造好的轮子,经过一番搜索,发现了一个可以自动识别验证码的三方库,而且是免费使用的---百度平台的 baidu-aip,使用方法非常简单。
第一步,去官网 https://console.bce.baidu.com/ 注册自己的账号。创建文字识别的应用,记录三个参数:APP_ID 、API_KEY 、SECRET_KEY,然后安装:
代码语言:javascript复制pip install baidu-aip
第二步,手撸代码。官方有更为详细的教程,这里给出一个简单的识别本地图片验证码的代码。
百度人工智能平台文字识别程序代码:
代码语言:javascript复制from aip import AipOcr
def get_file_content(filepath):
with open(filepath, 'rb') as fp:
return fp.read()
def recognize_image():
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
image = get_file_content('captcha.jpg')
# 识别结果
api_result = client.basicGeneral(image)
print(api_result)
code = api_result['words_result'][0]['words']
return code
第三步就是写爬虫代码了,使用 requests 库的话,先构造 headers,然后打开浏览器开发者模式,点击 XHR,查找对应接口,本案例中就是这个接口:
接着写代码:
验证老赖身份证是否正确的代码:
代码语言:javascript复制def get_zhixing_id(self, pname, cardnum, captchaid):
'''
查找老赖的手机证号是哪一个
True 验证码成功,False验证码失败。如果找到程序自动退出运行
'''
result = self.recognize_image(captchaid)
url = "http://zxgk.court.gov.cn/zhzxgk/searchZhcx.do"
payload = {
'pName': pname,
'pCardNum': cardnum,
'selectCourtId': '0',
'pCode': result,
'captchaId': captchaid,
'searchCourtName': '全国法院(包含地方各级法院)',
'selectCourtArrange': '1',
'currentPage': '1',
}
response = session.request("POST", url, data=payload, headers=HEADERS)
try:
results = response.json()
logger.info(f"{cardnum} -> {response.text}")
if results[0]["result"] != []:
logger.info("!!!"*10)
logger.info(f"find!!!! {cardnum}")
logger.info("!!!"*10)
#已找到身份证号,程序退出。
exit(0)
return True
except Exception as e :
print(e)
return False
实际操作中由于百度识别验证码的准确率并不高,我们可以让它识别错误后重新执行,直到验证码正确为止,主函数的代码如下所示,保存 ids 的序号可以支持断点续跑,节省时间。
代码语言:javascript复制if __name__ == '__main__':
generate_ids = IdNumber.generate_myid()
begin = 0
##断点续跑功能,如果中间程序出错,可以从上次的地方继续进行,节约时间。
if os.path.exists("begin.pkl"):
begin = pickle.load(open("begin.pkl", "rb"))
print(f"从编号{begin}开始")
zxinfo = ZxInfo()
for index,id in enumerate(generate_ids[begin:]):
time.sleep(1)
logger.info(index begin)
pickle.dump(index begin, open("begin.pkl", "wb"))
result = zxinfo.get_zhixing_id('乔二胡', id, zxinfo.get_captche_id())
##如果验证码失败,请重新验证
while result != True:
time.sleep(1)
result = zxinfo.get_zhixing_id('乔二胡', id, zxinfo.get_captche_id())
程序跑了约一个小时,终于找出了老赖的身份证号:
完整的可一键运行的代码我已经放在百度云盘上,如有需要可在本公众号后台回复「老赖」获取。
总结:解决问题的方式有很多种,技术人应发挥所长,提高效率。本次分享中的身份证号生成代码可用于项目中的身份证识别,百度文字识别的用处就更多了,掌握一些基础的爬虫知识可以解决实实在在的问题。
(完)
专注于Python技术分享
订阅、在看、转发是真情