Python Faker库的实战,用Faker库生成伪造的安卓通讯录
  • 分类:Python
  • 发表:2019-07-01
  • 围观(346)
  • 评论(0)

老板的需求总是各种各样的,作为程序员就只能想办法实现。这不突然让帮他生成几个虚假的通讯录。具体需求是这样的:老板给我个电话簿,让我给这个电话簿添加上姓名,公司,邮箱之类的数据然后导入到安卓手机的通讯录中。听起来不难,主要有两个难点需要解决:①.安卓的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}
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 条评论

Top