老板的需求总是各种各样的,作为程序员就只能想办法实现。这不突然让帮他生成几个虚假的通讯录。具体需求是这样的:老板给我个电话簿,让我给这个电话簿添加上姓名,公司,邮箱之类的数据然后导入到安卓手机的通讯录中。听起来不难,主要有两个难点需要解决:①.安卓的vcf格式的通讯录如何生成?②.通讯录里面的虚拟数据如何生成?显然,这两个我都不会,但是这并不影响我信誓旦旦的跟老板说保证完成任务。可能是我天生的马屁精的思维作祟,我竟然没有丝毫迟疑。既然答应下来了,就赶快查资料研究啊,不然会很没面子啊。。。
生成通讯录文件
首先说一下我拿来测试的手机是荣耀8 青春版(PRA-AL00),所以本文章的代码只适用于本手机,但是其他手机或许有些不同,但是大同小异,可以自行修改啊。
通过导出真实通讯录文件我们可以发现会导出一个后缀名为.vcf的通讯录文件,文件内部记录的就是一个通讯录条目。每条数据都是有相应的格式,我们可以通过用Python的文本处理自动生成这些数据,然后按照一定的格式保存就可以实现目的。
BEGIN:VCARD VERSION:2.1 N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=E6=96=BD=E5=AE=87;;; FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E6=96=BD=E5=AE=87 TEL;CELL:137 0000 0000 EMAIL;HOME:wenna@xiuyingyuan.cn ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E5=90=8C=E5=85=B4=E4=B8=87=E7=82=B9=E4=BF=A1=E6=81=AF=E6=9C=89=E9=99=90=E5= =85=AC=E5=8F=B8 TITLE;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E6=99=AE=E5=B7=A5/=E6=93=8D=E4=BD=9C=E5=B7=A5 NOTE:Lei Long END:VCARD
但是通讯录的中文都被转码成了=E6=96=BD=E5=AE=87
这种格式。根据文档中的信息我们可知这个编码格式是QUOTED-PRINTABLE,,这种格式常见于邮件内容的编码。知道了原理就可以通过Python生成通讯录了,现在就差生成虚假数据了。
生成数据
生成虚假数据有很多方法,你可以自己找个数据库,随机取内容自己组装内容。显然在Python中这不是最好的解决方法,因为我们常说不要重复造轮子。在Python中已经有大神帮我们造好了轮子,我们直接拿来用就是了,方便快捷。
Python Faker(Github跳转),这个库可以方便的帮我们生成常见的数据字段,就比如在通讯录用到的姓名,公司,职业,邮箱等字段都可以通过Faker随机生成,具体可以生成什么字段可以看帮助文档:https://faker.readthedocs.io/en/master/locales/zh_CN.html。很好的中文本地化支持是它最强大的地方之一,当然没有你想要的字段你也可以自己拓展生成自己的字段。这个就要你好好研究下文档。下面给出Faker库最简单的使用,并不是我代码写的简单,是Faker轮子造的真的不错。
from faker import Faker from faker.providers import company, job, internet fake = Faker("zh_CN") fake.add_provider(company) fake.add_provider(job) fake.add_provider(internet) print(fake.name(), fake.phone_number(), faker.email(), fake.company(), fake.job(), fake.romanized_name()) ------------- 高波 15367494829 liangxiuying@jie.cn 创亿信息有限公司 发型助理/学徒 Yan Xiong 赵雪梅 15273315215 jieshen@wei.net 时空盒数字传媒有限公司 招聘专员/助理 Na Song 郝建军 13974301066 qiang59@gmail.com 海创网络有限公司 建筑工程师 Fang Bai 苗桂荣 15189431825 wei25@yang.cn 雨林木风计算机科技有限公司 洗车工 Chao Meng 何勇 18523647816 zliu@yahoo.com 思优传媒有限公司 财务总监 Gang Mo 邢凯 13270120305 ohao@en.cn 恩悌网络有限公司 店长/经理 Jun Zheng 黄桂芝 14722785870 lsong@gmail.com 四通传媒有限公司 理财顾问/财务规划师 Chao He 王静 13100215209 xiuyingzhao@yongna.cn 国讯科技有限公司 地勤人员 Jie Tao 胡英 18167345031 ming44@xiuyingtan.cn 襄樊地球村网络有限公司 总监/部门经理 Min Fang 彭兵 13721006931 jing80@yahoo.com 太极网络有限公司 调研员 Wei Wen
这样我们就很简单的实现了通讯录数据的导入,只要稍微把代码整理一下就实现了老板给我安排的工作了。完蛋了,老板又要夸我了,还有点害羞呢,嘿嘿嘿嘿嘿。
import os import quopri from faker import Faker from faker.providers import company, job, internet fake = Faker("zh_CN") fake.add_provider(company) fake.add_provider(job) fake.add_provider(internet) class PhoneItem(): data = '''BEGIN:VCARD VERSION:2.1 N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;{item[name]};;; FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:{item[name]} TEL;CELL:{item[phone]} EMAIL;HOME:{item[email]} ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:{item[company]} TITLE;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:{item[position]} NOTE:{item[nickname]} END:VCARD ''' def __call__(self, *args, **kwargs): item = { "name": self.__str_decode(fake.name()), "phone": args[0][0:3] + " " + args[0][3:7] + " " + args[0][7:], "email": fake.email(), "company": self.__str_decode(fake.company()), "position": self.__str_decode(fake.job()), "nickname": fake.romanized_name() } return self.data.format(item=item) def __str_decode(self, value): return str(quopri.encodestring(bytes(value, "utf8")), "utf8") class Genetate_Vcard(): __path = "" @property def path(self): return self.__path @path.setter def path(self, value: str): if os.path.isfile(value) and value.endswith(".txt"): self.__path = value else: self.__path = "" raise ValueError("路径不存在或者不符合规范,请重新设置") def generate_vcard(self): if not self.__path: raise Exception("路径没有设置,请先设置文件路径") with open(self.__path, "r") as file: original = file.readlines() with open(self.__path.replace(".txt", ".vcf"), encoding="utf8", mode="w") as file: faker = PhoneItem() for item in original: file.write(faker(item.strip())) if __name__ == '__main__': vcard = Genetate_Vcard() for x in os.listdir("data"): try: print("读入文件成功,开始生成{}".format(x)) vcard.path = "data/" + x vcard.generate_vcard() except Exception as e: print(e) continue
共有 0 条评论