python 爬虫之字体反反爬

2018-12-03 09:26:38来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

爬虫常用来从某些网站抓取数据, 包括文字,图片等都可能作为爬取目标。通常情况下, 文字数据有更高的价值, 更容易进行后续分析, 所以有些网站就将关键数据以图片, 或者自定义字体形式来展示, 这样一来, 爬虫拿到的数据就会难以分析, 分析成本增高, 收益减少, 就可以降低爬虫制作者的积极性。对于图片, 由于网站需要保证正常用户的体验, 所以不会有太低的识别度, 用普通的ocr即可拿到真实文字数据, 而对于自定义字体形式的反爬措施, 爬虫往往拿到的是一堆我们难以直观分辨出意义的"乱码", 只有与特定的字体文件对照, 才能明白其意义, 所以我们就需要做三件事:

  1. 下载字体文件
  2. 分析字体文件, 确定编码和文字的对应关系
  3. 根据对应关系,完成转换

对于1, 简单情况下, 只需要找到@font-face, 直接通过其src字段指向的链接就可以得到字体文件, 但是更多的网站是不会采用这种方式的, 因为这种方式只要弄到一份字体文件, 确定一次映射关系, 爬虫就畅通无阻了, 根本无法提高爬取成本, 所以大多数网站是用 src: url("data:application/octet-stream;base64, *******")这种64位编码形式来传输字体文件给浏览器的, 这样就可以对每一个页面使用不同的字体文件(主要是不同的映射关系)。对于这种情况, 我们只需要对其base64字符串解码, 得到二进制码即可

 1 import base64
 2 from io import BytesIO
 3 from fontTools import ttLib
 4     
 5     
 6 class FontParser:
 7     def __init__(self, b64str):
 8         self._font = ttLib.TTFont(
 9             BytesIO(base64.b64decode(b64str)
10         )

对于2, 简单情况下, 网站每次传输的字体文件中编码文件与字体形状(也就是文字)对应关系是不变的, 复杂情况下, 同一编码可能对应不同的字体形状, 为了应付这种情况, 我们只能寻找字体形状与文字的映射关系, 在通过编码确定特定的文字形状来完成映射。这里我用实习僧的字体举例:

首先打开实习僧上任意一个详情页, 检查源代码,检索@font-face, 将其src中的64位编码字符串拷贝下来, 

然后使用fontTools将其保存为xml文件

1 ttLib.TTFont(
2     BytesIO(base64.b64decode(b64str)
3 ).saveXML('./font.woff')

然后打开该xml文件, 可以看到其结构大致如下:

其中cmap是编码与字体形状的映射关系, glyf是字体形状信息。那么只需要把glyf中的字体形状与特定的文字对应起来就完成了第一阶段的任务, 这里需要借助百度字体编辑器

这里我只用到了数字, 所以只列举了一部分:

1 _glyph_map_ = {
2     'uni30': 0, 'uni31': 1, 'uni32': 2, 'uni33': 3,
3     'uni34': 4, 'uni35': 5, 'uni36': 6, 'uni37': 7,
4     'uni38': 8, 'uni39': 9, 
5 }

 对于3, 这里给出针对实习僧数字部分字体转换的简单例子

 1 import base64
 2 from io import BytesIO
 3 from fontTools import ttLib
 4     
 5 
 6 ## 实习僧字体解析器
 7 class SXSFontParser:
 8     # 字体形状与文字映射关系
 9     _glyph_map_ = {
10         'uni30': '0', 'uni31': '1', 'uni32': '2', 'uni33': '3',
11         'uni34': '4', 'uni35': '5', 'uni36': '6', 'uni37': '7',
12         'uni38': '8', 'uni39': '9', 
13     }
14     # 样品字体
15     _sample_font_str_ = '''
16     d09GRgABAAAAACiQAAsAAAAAO+wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZtBmSmY21hcAAAAYAAAAO0AAAJ3GjR9tZnbHlmAAAFNAAAHlgAACfUsfAWzGhlYWQAACOMAAAAMQAAADYWqTgPaGhlYQAAI8AAAAAgAAAAJBCpBlFobXR4AAAj4AAAALQAAAGQUfP/MmxvY2EAACSUAAAAygAAAMr1ieq+bWF4cAAAJWAAAAAdAAAAIAF4AF9uYW1lAAAlgAAAAVcAAAKFkAhoC3Bvc3QAACbYAAABuAAAA4PWD99UeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/cg4gYGVgYNVmD2FgYGxCkKzCjK0MO1kYGBiYGVmwAoC0lxTGBwYKr7/4yj/+4LhM0c5kwRQmBEkBwDMmwxzeJzd1stvFAUAx/FvpdYXatVqW98CKio+W63PtlqxLb5bUOsTISEkXDhwIOEiBwgJB+BEgIQQeuAGB0xomgYSuBjgAglcODC7293uzu60ne7ulIRQ/C2//g+a7ubT7Mxpp/P7/WaBu4FFskLqdbicOmofl+hs3Z3zi7j/zvn6RYmO/+EvGuhja9ATDATng0vBlSBKbUztSJ1O3Uy3pHvT/emh9Lb09syuzMHMyfHO8YHxi9nu7JbscPZariF3Incmd2GiY6I/35hvyh/LV/JJIVOoFubCZWFfOBgOhUfDkbAQ3ih2FUeKmeKt0qrS3tKR0vFSOWqPuqK10YFoNLo6uXly/+S5qRVTo1Nnp5un98VL403xnvhwPByPxXMzl8tryplypbKuElSbq6ur15PWpC1ZmWxIdia7k0PJqWRmdmx27vZtXdHCuZKF8KpTwhbCu3YlDSxhiF94nPvo5jne4i4e5Bu6eIJn+Zy1PEUHS1lMD4/yMx+zUs16UY2rp5PlvMF6WvmRr3mXn1jFe3zKK3zGd2ptM2v4kj95gN9ZxkO8xjt8wJu8TBtf8RFP8zDruJcmfuUPnuceHuMlXudVvuVJPuRtXmCA9/meXlar4Y/wDJ/wA1+o8Y0M0sJvtNOvy2j4L8PwP3ktrv2p/3v+aL1snaevGPSY7jfBgOnOE5w3ZYDgkikNBFdMuSCITAkhtdGUFVI7TKkhddqUH1I3TUki3WLKFOleU7pI95tyRnrIlDjS20zZI73dlEIyu0x5JHPQlEwyJ00ZZbzTlFbGB6z2Xxm/aEow2W5TlsluMaWa7LAp32SvmZJOrsGUeXInTOknd8Zqz6XcBas9myY6TN1got/UEvKNpr6Qb7LaPcofM3WIfMXUJvKJqVcUMqaGUaiaukZhztQ6wmWm/hH2mZpIOGjqJOGQqZ2ER009JRyx2nM2LJi6S3jD1GKKXaY+UxwxNZtixtRxirdMbae0ytR7SntNC0DpiGkLKB03rQKlsmkfiNpNS0HUZdoMorWm9SA6YNoRolHTohBdNW0Lk5tNK8PkftPeMHnOtDxMrTBtEFOjpjVi6qxpl5huNi0U0/tMW0W81LRaxJtM+0W8x7RkxIdNm0Y8bFo34jHTzhHPmRaPmcum7aO8xrSClDOmPaRcMS0jlXWmjaQSmNaSarNpN6nOq/1Gql43bSlJq2lVSdpM+0qy0rS0JBtMm0uy02q/w5Ldph0mOWRaZJJTpm0mmTGtNLNjpr1mds7o/xfEXcO8eJxtWgtcVNX2PmufxyAi8sYHKcPTDAmZB0RIREhEhFwkMiUzQyUzRSWfpESERCMhIhGSEQHhI0IlQi6iEiKa77yEpGZGiEpcU0ycmbP473NmQO+9f+d35swczuyz93p837fWlgGGGexl/BkHhjBMgMrRYYLDJIb+o98Gu7lXBW/GkrFjGHsbRulqa8O4u9GP0iel6xywAQK9eEvfi2IbPAVqPI9HSA8UQ4WxG9fgG5AD74ufkpXkI4YBaVBOI/gyIxjmcdAobXmNp62S0xizYQ6WEG+YvZMrWlRbql9vvteLPttZvhdCQKP2cndTaLQqfydHB6IARyU3xhgHzQ0bCnRnGr+/e+7O9g78grTugiMNF1MzN9cc23ztUB7easevOWk8upaxdDwlXYmTyl+rsVG6a1Sutmrl0KA2vOMEcHSgC/T+5Iu20n/inPfXw7v4+1d5RT+23sYTVT/gT/pLm4Bd/3kmeJWBw+DSA7POVODZVzi744XnBpk42WZ03snCKJPNwN3W3VapAZWtSmmrDnAXFMAltzaJvuSb31sxjeOsp6AK8nEp5G9kjUZX8tH02V7/EGeY56uk44yhPpHmayOt3lbpqLSlk+XoNJVu3ntLdpa2HDs4p5joxcZXfO6BHXaieHFp38L98Hi5NWv/DUbxA52/4c3QYX/OoTZwYtzo3OiAhFXR0ezkRTPUt0p/Z3CQrSMZW2D1azOP9xN+6V/Hb+Otn3vxLrwBrhVzxdivNqWXfvpxZjkfEYJleO5fqL/4O16C5TCT+v73KUb4rLOxoHRfrWQOky9fomsRGGYEuINSo+ReEst+JKFGPftv/rg+gJ/3DcOw8vyi6PwcmYnM4/SHHhq1h9kznK0D5+7mobHxBHlqjg7OWqBmME0W6vAWcCcO3MZfYSbe0J9ChGgoyViWnH93AI34W9WmD8rZJ9+/t/vnE6WIH3PrsPPIH9dqYdImWJ+85r03mhcswpupHSl5n7z928PYj5Djz93kATtbwVugZtKoGZW/bCw3b/tHjHUgveDsH4Qs/OuHQQbG/HodOKzBn79avrx087rKik3vlZ+PgkjwJaQZrNq7wBO3YQXORH8N51Ly/derv/6lachWii72Dcka9tTbroqWgWD2jRpGtg/eVPwilDIujKdkH08aWzS6pJhQ2jrQsPXyptPR0C/0DzTmbMDLm7GnH9zZvwqgWfybaxU7oe1szBJLhxR1Cp4spOlqWYjVEcEQTDCnoGAclw5eOTnYaUy7IkTHWM8lPfpufhzJM/qIqbgr3AvUJJIN1V8d9is/kvrVkWGU7vRhUny7jwAVODmrtAH0zI+8i5VWzjxxw5J+wqLXPfAfP54b4w6hf6ALed4h2OIFsYG1ZFmx58lntNOIvWha56+KfmELjX0vZrL0IGeFlzfHCwpvbYA2QF4xUXh6ebOMtEJQKRj6N4anl3lfcDufERqP1uJAfMLs+eHVZeJChY8x8GQzG524tBlT0NovhIRAUrsXzCaBwWqx0VjAxRpqIADxWmrU7AleFh6VHsG7ugoKENsmz13Ku+AkvBoZBV5wzR/9O2Jnw7i4AlOM4KAiVbBnFDKqULPTmbmDf4DC3ZV6gSgE3svbI0BrL/mHeqhBaKjSF1bx1nN1E7rxb7zGPhOG19SRYK3WsJjOL8Y0wX6gd80a1o8rv0PuiCf3Xa0PCStrzCAT9KX8PNEjmTHHwQPFJeFLZiQzlmYKA0pblYwM1O32Ts4cNZNGigtbLXUEtRwpJRF7SJRYt0dsqBcs8PDZeRHYBY3VOL9zvm7DHvYvUiPG5hmKuGTxcHJEW0F28Dp2TJ5RvZjvvbpkVeU+0zNFRZewnRlHsUPzyDNtHsadyRtKkCdi6y5FoCJAnoHZELZsD5lfBAQRgy9Z2TUlZuAdLPeNgF1gIZ4wlrFMHrrmQWCeb1hJZ1b+vgg86RcKJCqGuw/lmJhvOIF9JD7BuoANQjs8GRQMK4gTdBrGcfGGUrYBE1B3Mqiqf8nh1pt9oeGVdbugxOynfysKhK00kwOkmVMvgZKwRCnP3JU6yJ3IqaI0ndw1oA2QDUhx29HdVksXQaOPMfZzk4y9rG6M07hBZladtUMOuFg7OLS/Kt4KDITbrw4yKzHILxB2LO0THbZsxX6wKujvT1nBWeMlrOM/z8unYdlOc+60kBTltEsP9eLruDpCDa+QV3Ek/jMoCMbD7iLR7+lQsj8P+tEqT/xEpY0Py6w0YxLNt+9ovlkwNgxDze8qwxBrq3KlF5Rt0ADz4CecgnnXfgNveBH34C1hFC7Er7EIY/g5hgQII+HgMZy7Ek+NlHJXhgw6oK2KT24z3m5rY23aSIMYIYwSXydfDt3PPqD38xIfS/eyD4xn2shbwih9+RDv5Q3znhQBMkt509nJZAt5bVBvAEdsvHv8wPdNuIM8Jx4URt35rQv/sGDHiYUVxfCEmStS6DgKOcYk9lRyKfjscXyOm87P0Vfwc2g40qcweE/RTXPAnmaAhgliQpgwJoKJYmIkGqYoYUpG2XcKOgxFJqVG5WjOUQWNXIVSUBB3pRy7EqrYKym92mpZGVIpftJ3nh6gdHycaJTjQsJWsGMyw6OIVUmO3sjGQHUWVGeIbhkbuE5jswcps7RyuIPFVhPOFuRYW1iKMaH4dyfeycgAa7wjHVQW+eAF2Ce/y4foJp2PW1pyF7KyDIXWNoGzXDEUytRavrG+3njb13dF2o76dDRGJVitC1kKrofBCyvHQAv4ZoCveL6hoQH86utlk8n22EDtoaBRHs5EmqwnrZWV1skL3sMLFWRckpH0YZzLwkK21SNEIig8qSXYSZxPkcgVhXKFnLUd3sw7bW3dWLTL0oqIfSNeXIh9k0P0cdMVWCeqt27CAbAoAAH1S5IshCtt4Wss7FJDZuWkCTqRI0ay0piZo1NE3EHsEDguKcymOr9B3Hy4NCgqO3dxt7HFTQmXdZCJaTqMdHFZ6BssVl3i4qKtFxJbb48x6GXmncEPFC38PSl2A4YZ0FEZxC4RBaFKJOzSgVUTeW1pqf5EyRCXLxMWMKOZ8VK0a9wpjxONDePqTBOcNesJJ1ethlvWwq0dPD8A1MgLuZYfvk0vqf0GJtTWn4cnEOzgxRqy0zjlw/03jh/4+afPzXZ/oFgnzJSR+ElGRadnoxAUsn3HUhfQL8O0DNIsqT800ovGoukFNOpgjY9fUVDghkmuQtlAbrXFmObkXH0xcOwsMbSonBCcDZUlUImzCWeYyyaJHexy5Jp62qOCDzdXQRlr8aAFkSNC8EKrLD7fWCJ2pbMnTmTX1GSfyBZbwQr7h3IYVlA7sBJ6qGyrW4QFD7ZLqozy2DVhL+PK+DLBch5FS/Ej5cij4eD+yEtJg8cUOOaDJ6w2QHAWeLpyO3ueHgrC0iHsZQYgF3hrsSqATC1Sz7UeFx4RfDqrNatNB02+YhfbZ1yjA20eaHWGGK/kRa8Q7hrGTDheMd8NQ7LDwnK0C0m1GFe+blV8ZiS7N6NTTN5D4sKEENCLOpIqFpFk0YtN6AQuBJqxAVowGCKQCcKL4g0np5jQwFmFSlfyKozTTsBrOM8D8sjSDGiLzC+O1ZlxFVmunltCQfQxqqokKHQ06WKp2vFmHxF5jrCypYXL0F/4C/99/V+pfPUHJTXluVsaSsRFwoxDF/FnPfbi3jrw2XTg9oX9P57+0jz+nxSrvqejm3QCfUkhwtg7Cwpz7A7xt5RwXhSmW8TaTV9TaeCSWz7Zl1J/GCkRk9gxxp4ygx6uEi8q5D4jwZB09xSlnlDI9X3ztTws0WFsnthFXPKgZkh3v0z9bStjvI00fxnn6eJcbbmXfxjYWEVXs/EmvEvSIOaHAnGzsEAMOIvTzHjfz8VRfGVGEHdWFnesJO6owlAB24+58E7XT7YTOZj682+wBj/rOmM/noNRXJz4k/gLzHMJEmKxlEwkKsx108IJRmIOvKHoFd6iY3pTzH6aoVUJDSJHonCi+s3Dk5NUgqcXSyPPRvpoSwPM4WmgNnLTwJCucX+oa+i71p6c4MJ29AzCogg1bsf7eBvnqdWwGUb2vEV+RSus0YbAJNYn8ZKlgAONxibOEvuy5oUjFGbgQLFOl5/OCgs6LmwkFVT3VhytCpsduail/oOoiLcrr8LTrFUQ5tWGBRWB1XlMnh0XdtbYMDd+35LMsBWkLc+YncBnFJWkNmYayweby+ExGQ/uKnqE1ykOT6K5FPoQh8HOXoJayfEentTxssdN8og6hSi8eDPzaB4JCQky2BT2apEYW2Tc0boYeyBwQ6bNOIiH2T4fbwUnvBkTW7wmNTpvcZkr2UGCMQha0ZLLRQt6DiLB+h62R4wlNcILYlxcnJhF5dnHmfCU3ejwCJdYncsY3JeJA+FxtfML5hjfZJuwqjuhCyZlgU1WFt7Owo4sYT7WmjD0V0UTX0GxQ2GqTKTkPivMe1BaoMgY2MBX7DHkVsn3vU6xZDyNOVoVOCulNdvLS2LNC2KVk+B8KgbC1UixTOFguBPJpkD4QAR/WnRbxcaPZG2KoLuoCMcZZxWylcbbUizifZo/Sqo9aTkmjaY1WUmQ5mAnaX+WKjcX8ud64z72zREiEQ4b+4jAphu3HyLNcYFi6ukdonrycniGPFWUC4lFRefwepGY1T4/HBRkrngSv9OaeKWHNPPFjANFAcHddSy4a1S2AbIvJAwIIM2h7+DPTU0/gD3+GZUQNnWkO7xANpaBZQjWl4nl78z1NPNTN9cr17F0HLNK83d29HKXP9KBuN7dVAPvxxVwGF69sqXyGIoUuPz+7t4VOhu+hkRYBW3PnEukwu0XvIkHkk1j8lLtPva/xlSaC3eZyPk5PVRq1uACaIU3DdUNOChiPfgC7E3DGjJ2cSbshDdhEZyO7XgXK/EPvIyN4fDVXpkD7iouCPspBrrJPBZA81PqX9Cle5sYwGmapO29vKWYVVKUN4EXr7J1GOY4qdYE2ctUOEUXsUtOxOdb2a1LjhdbsItkhS3ckBb9JnGPXRxTlPgaWTuQKKwr6Vm8w9KuIDEdk6jT14ktJNh04F1ebShr4biYCEsSj1xe8rqEnCVhPhm5szYs1GUayv4mhItLsMlgabXKurRjefuQrnWi+tFG0qlSTWpGPLkcdcI+sWHCSL6tjbcdQ/zvi6vIYU9HKhpGid7jJ5BScexQ7S+4UVuPlLpPct9LtrGr9NlU+7u7MUlQCHPgOcjBJViNdbjiPEy8PgDj8dZff2In6YfV0IgxWI6bMIKqviV4Hb+B6eABPpSdqszPGaWIE6bSav4pOnVqV2pUCoZyxaTwlquo/yjrtQFenua72KG76DWYtWr1qjcist9cvXJ59sxZ63PXFApV3en7LO2qVqXrM/d88CGxSE16e2Vs9vKsDZuykpak6dbtyXyX2xxy8Oi5M/54907LqcgdpddPTcfXFR4PGtu50ETrpXyOwUk0/pkXXvbdH1fU+DuKHXeim5qvtMU8+Os8MxzngdRO7tRKE0DlqlH7grcvyF0bKdxlWeUsNdU4pZuXd/rzfW9DRMS6qhsFoO29vkTXnrs/7UxXHXbgg8R7geAeEtvzbHLszNRj6UeuBXa+sXrx3FUL3+nMPtmp8hrSLxaW1LfjTX0kc8PhkX6D6WxhiTE3sM2R4wQnPHodn7kMwY6cwLvAjKMQamPJ8WPATxj14C6XGB0/80VDmTDKsHRGbPCbXL5hQdDsZ1/hPh1eH7uH6gI5j6XWz1Aeywujeczu3rj/Nl6Cp8GiaMm7n1T9dGznJxv9o0F9D2zgJW1zwo3mQx1zTb4W73PL6FhjGFp/edrQ2lPjRFl4WItSi6k0KlY7LEa9uWXintNFB3bBVm6D/qweHLovv821tED1xtJ9e+CxOnhNLH7p4CKoevccTP6blo4v1hRiaHr9rVM1nWdLh/h/DuV/KzkXzJlAzcTNwXvoTcfi4IgRrYijeEtYYLgDBrF3uPe1l851JONkiv+hmDf1u6RWpLAA/EF4QMP9PA5gR9uRr6pqaqoqDpHHqEyehmfwLuqxCQKBP3TpZ9jacW3Inol03ImmjhqVVHK0aIeixRws1CLeywt2/5H0Wf3SB3Wb16Z9PnfVy/kHMh607kn/99uFoTOfitqyaOveqQdj4z6MCppe8E7Rt88OxYcQSDWLKT6GNItJsmgD7IfOQiDWnbxkzXGsQ18r1p68bMlbcKP7vuuxFEYQmw4uzlDNWvgHTg4x/s3FGU96hgZMZacaf/QI8wliNaZ1gKKFYqWtxO5mQKQcYSd1D2whkH0s8LX8+dEprFrvRbDedz548OvnZcZvWBNWhjaiDnU0REJIqGnOFHdPCgelHOLN/byHI/4/bb2MEnLCqGMrQmYWJ0Rmsm3GTNLet7TG0q4yKUNsLRXPT+MswaHovY2RGzLDirBXdDByYXMtM4nW0MBFDPWPfhNqhX9Q746X+0dS20Nrb6pXlMPPk6Sog3SNwJRBJjSqOcyXD8TuVQ2WDvWLy4zADhpt2NuwHTdgW0jQeXBrh3Wk9kEPdnCR86x2QHQ+pLeRdsyENFkD36UcvpY+XbIa5Ql7U9cOTF0jtryu7tIECCehIT5iLQ2qDrHSJ4ikgB973DBZkeUr3uyeHwdq6EZ/LIpMgNmEmNZCY7yYYsJoitUT5a6ItD8gKORePucOcvtBrRxqQ7TBsZP9WzbuOIi/XcV7dVsq8FLb7c9346fCqB++TG95nLP7saTtPj8Xx29+7xfxHbFry/tgOdT/6KbPGSErOrNaZ7vFXWSy2N7GTuDniPoacQ69Q+pjKxSdwm6qlCZKfh1WgGbdbyfrfnPRbRZ5EM7nlhr2lWI/Wyt2zXw9LO7S4sopU+FCOakVo9mogbm83rCPiyGPG68kJ3M6iPriQ18/cIVYvzVLIQhbC7CuAIsxaYgDD9CZ2A/1ZZ1k3S/Bo5fGVsUf+NN4T+kgWLQayN9aS86ylftO5a+uMByiQDgv3jmslHt8uN+kksdxkUfyhSeGOjvyZomz2bpe7ryqFwdfSn81rw06rgGDVaGvRYkbez/aXbINqt9/TUwVRnW2YNM8fnzSWjZXvFyasTb7YQ/5FVMfasQjWM6/Ih67Ip6/Al860uwcDzslvKbTmx48Y3okd+DhvsIxk09GSLJDI28tHDN+wL5lWMGuNp7hEvlz+qt7w3nnfaY67IHiivC1qacP/0/5RfHCi5evyy0jLxIGlhvKn3ya7RQnkWxxDSkT55Z8tbwwUMyFceXlL71SsmD5BHY9LIHDE4rzdFimwwIdWvCd/e3aNCgjwX69Z/TPcasPlkQP4Wo9xWMbyZ6ejuZS7H/qTNfhMvPsPfzzj47lpjITr/2zpIQWaL4XqSrEHvyuDp7IomXmt2dOfzFsD9ItvCfpV2l35zEwr0qjMoEs6Q4IrQcWxeaDB0/tiPfnmx7rqigzxrI1ZdX7frSXfj7oL96HLcJMxkJiPXu11t/JQXDzsrch7jJj+Y8FVVHE25EvLI745ddT0S/ERNxo4TvUz0ckRzyv/5Ci/kX3vX6wkgsf8k8CxXu7/6w/5eLayZFL+OHB+5V0ne/11TWRd+Hlw1vFj7i478/d+NWcbwwn9WzktTzyS2eWmZqwooD+MP70cx5snvu/qsWzXNxv/aOHnjmZcsB/xRM3GaNacV47WCsF3nIsjJdQnqL7zddD459nxw3bjz1If2vanzQ3itkDxsXkA/EAO1d8n6x/ll1WFmrMM+Po4GZFG39ZrolGPqyKpHO9oHuQmqbQDaS28x36SfzlPQauii3bZebXjxWNvEjjwEHqYNGKZqhEYs0lUjT/4lhD0QY8LVzS4xPcCy/BewN5fK7x5WfYE84wK5dNycvDTsNZHeeDkWatskxxSfhG5lZzIfmwx/AQa6RjElsqBpMW8faH30wOk+JYEwpH9hCjyNGLwWzyQDQPWAynbzeHRUEwtPnkZ0EVzipG/2IkhfKzFIouYRNjLddjKkFhB+YazJVN9q8ZOXGA7IkPFavFX8Q12jdggLvd3mwcgy2JcRDLvmxsw/eizDx0XXFb+IqykIoJpIuQ89GdalupHWDeNCCsDJm0zDD1Ks3L8BScOanVBEo7ezuurSTqRXZEw9SbB8EvXI29J47h0cmhENF0+B+PT54c3mNckr/oHdSytbhLwkqYLXBiOyY4RcXwZ9FpeuM/ha/Ue7fpxPNY9q/PoqO+utjVFBzV+CvYwy+hAepwcEXjInt77vvcXBRyxd6wWeFJcSVW1pwWXfBX8BnCyo/kvvVoKdqpKyXhYdYg/EeXd4jrt10mMe3bbo4cxY+07pEsKowyRpHMiS9FeIlpZn1EpN63ldRFfCThSErfqddDQub2txF/WkaccvlhChSzvwxj4AgTfj4OD73MjTAeYieY2ImsFUbtQ5u94n0zRnia7gcpo5S0xKXsRDy3bUPrbdvgDp9kmL5zJ/fPnUO9MQPl7e3UR94m5vv/GExWJo/iZgqpww/+MS8oqml2mfcUiC6FK+hGXMWrpWKUWAkOVeVRCTsWpk4g00H/885Af4iBEt9tH8JZ9NOhoBPDSSNwUETC/W6c1D/PLTu4I8G8N2ph0v9D2+kP6U1pznSlrfDsaH6cA8IyJHYuguUhGA3H1bYKtSOcA8KRjftSfAxvcbmT3lty2qignNK5LvwTFef24K6pnyvS9X4rY7Srac2O/ynDwOPhQuVil36noU/6uTuYpq+qtrIr2ZEjBos+oEXdopWVazJcWTfO2nDH2AwhzXk9WOXBHig03hkgsUk22aQD2xFOJuzbbrjMvpy9Mp5bXIj9f0PELCzB7mizD14RZgzv21N57MFy5oqUvvO09PIPgEdKU2HGCwvzcPB3PI7LaJU6D6bBx3hzkHm/LiUxVH/90ToVlzrrgGZuE8TBWmiQC9YfMXGabtF49uL/lKzmPkQ49cEoKUaVrmOlXT75xIeLe8SjbZAFa9vIanEZWcd+Y0zEJ6GZ3W+O0+Om342QRMRDZD6O5DiO/gNmgAdr9RjMpVkxRWwlGrZDjIP5kwPJt2buZNsplzhICGevVcndGal48tLYTAHKLQqwBtP/B5gGxys6IK+ZX3n1yyZYBpFXj5VDZPailMT0So5fhIli4O6j1bQGVfnC6Cw8bJc0e0ZSbfbi4dpHLfeCnSXfy7Z1FKih1YyrnSOtVygXKTi1Uc/XVzRsz8eJeBe8oba/BXQb393tBPf3Hln97SLwA2uEKLxhCCosr9aZ8AHyZF61epRXaQ59+vxbL1A6dTbx6FvTp+sTJXIy1zPXTfUS5U/1EA3+F5E6S91c4XpLSvqS4pa7KVspMa76fdku5fp78A5ZX7v9RI6YQz6Bpw9vEz/m4r49vi75GoaY8feWwih8R6M8gKGlgb1qeCNIUJgj3FtGXbsAqiGGOj7EU+WgsOMVHqxpu1TraYIDR9bbXkKHO/06sMO+r7+w5ArKdad+t+vpxFXLXrowGDix9Ek/+BL957BHSyw+h/0bsODzt9HHN5C4uQpo1VG4I+Bp1u5sSa24eGFKEHkABbgkE8/ZO0SH2jhgMNSOm1Do5AzTNsC4rsxanWt+biYas8/WiPGtOScIj09jT1gY+JDYNH/KW1cnl+iycIMbJF6t9Rru8y8b6vNL9bCgdCO2/1N70xDylnaCUhHPGcCh5+pCqezemV2yb/fHRXsBWfL9BepzQukhipbcwR8c6DndcP5cyXBPJJRqCNuhnSZzilBlZ6viQo9yy7pxdTOQ9B1Hq9ugnRSKm/Dbg3nkPRl7bil6hQrq7+eZF5kZJkaUyZA17WRKbpE39yXIpo7nH7mkkS4+BGdHpUymJn/Ke0wUqRXahS2H62BCyGSxYVdjaROxKO5yCVwcyl7Jx8KgpBZjErHI3+XvuzgM+8Au29XNy69lRb5/MKRgVFAYITfBDa+kcXFiJKmXDhKQmrPqcGx8eCfZIKZGJydGRKXb+eeExQnBBqN/Y25636youFQP35zQBGjMAY9sf9/IULCDWX7ZaTlLk3LwUg56RJNqSrBXSTNek+wn3udU5n0HGOLAZ4DChQktVGipG3xB/ZTmw7CXMeYiKMfwgh340oxR4A6bPU4lx7lY45E5E4NYqScgyJq/i2oMO1ljSB35iEf3h83bwxwPSq231Fk2G89B8WhrWfq/Aeyju8OecuN+XHR0BjuvsI6zbMnHQbzIMnDaAvBN4jI7vyTtbZiBPgoyUbz3GeRGBuLnW5Zidog/fPk8hnTgpa1bwQMvSQdJT12zOCN+r9Uo7pBOZ6hyiwvyxlfhI/U00pffUZAHTlFHthdc3FKAbj2RMTAKtuFMvB+jBgVcx90UyfeNhYPUuODRFpddNjuHYf4PbBCMynicY2BkYGAAYvvP+fbx/DZfGbg5GEDghtp3fRj93+jvdw4utr1ALgcDE0gUAD72C+EAAAB4nGNgZGDgKP/7guEzh8p/o/8POLgYgCIoIAUArBYHDHic42AAghQGBpaNxGEOBghm1USwkTGbBBAbANVKA/FTIJ6GKs8qB6GZFKF8GQjN8haI+bCbyfQbqC4KiD9D9YgA7WiF6psHpFWANDPEbJZoIC3GwMC8BagmENMsVlagGgeoWxuBfEsgzgSKfUO4h+kYECv/N2J5BzQH6CYWYyD9HrvbWBcC5bSBatKAeqIgYuwXoeYD3cj6Eyh3BYhzgLgL4m/2ekRYgOwA+8MGQgMALgwgWgAAAAAADAA0AEoAcgCmAMoA9AEwAUQBigHGAdQCHAJIApwC2AMSA3AD1AP6BBIEIgRGBFoE4gVYBXAFngX0BgAGgAawBuwHCgc0B6YIEggmCFAIhAioCNIJAglmCYgJvAocClQKjAqyCuwLCAs0C2QLmAu+C/gMMgxeDJIMqAzoDQwNPg1cDXQNtA3kDgYOLA5KDmYOhA6cDrgO4g8YDzwPog/ED94P9hAOEFQQhhDQERYRMhFSEYYRshHMEfwSdBKmEsQTRhNuE+oAAHicY2BkYGBIYQhm4GIAASYg5gKz/4P5DAAb1wHYAAAAeJxlkbtuwkAURMc88gApQomUJoq0TdIQzEOpUDokKCNR0BuzBiO/tF6QSJcPyHflE9Klyyekz2CuG8cr7547M3d9JQO4xjccnJ57vid2cMHqxDWc40G4Tv1JuEF+Fm6ijRfhM+oz4Ra6eBVu4wZvvMFpXLIa40PYQQefwjVc4Uu4Tv1HuEH+FW7i1mkKn6Hj3Am3sHC6wm08Ou8tpSZGe1av1PKggjSxPd8zJtSGTuinyVGa6/Uu8kxZludCmzxMEzV0B6U004k25W35fj2yNlCBSWM1paujKFWZSbfat+7G2mzc7weiu34aczzFNYGBhgfLfcV6iQP3ACkSaj349AxXSN9IT0j16JepOb01doiKbNWt1ovippz6sVYYwsXgX2rGVFIkq7Pl2PNrI6qW6eOshj0xaSq9mpNEZIWs8LZUfOouNkVXxp/d5woqebeYIf4D2J1ywQB4nG2RR3fUQBCE9RmMyTmbnDMKEySytJLIOWfWu/Z7XLjxHj8fVK0jOtTMVHdXt6qThcS+5eT/35wF1rGeRTawxEY2sZktbGUb29nBTnaxmz3sZR/7OcBBDnGYZY5wlGMc5wQnOcVpznCWc5znAhe5xGWucJVrXCclI6fA4QlESipucJNb3OYOd7lHTcOElo6e+zzgIY94zBOe8oznvOAlr3jNG97yjvd84COf+MwXvvKN7/xgygoz5qwm/Fn8/etnkQozYS4shE7ohUEYhaWwWvqHrkvT4fRdKtaXYvusFhvaZjjLps50tnkuPhb1kO3UwanSzVSvWbxTdmpqITcV33aaJSjqXVBdmA2vWHf98IrjNFHKlhFLm6HpLDNtbPJyYmdlelVeKdtmkgMuKpK7Vq8V4ZpUei+/vPK8fAm6B7srN6xJUXyM42T96JecCDE1x7rcHJH/LtgfOuNW1UMRrz34qbnsJ+qiSFAkTIWqiOKj+DgdtzVurVL36LPe3o32FXwhF53+zUnLyXM31vVSc3M5Wjr1H51QnpeHQUywbRljFX2wLSke/cBVzjRjNe7cJclfjO7Tgg==
17     '''
18 
19     def __init__(self, b64str):
20         self._sample_font_ = ttLib.TTFont(
21             BytesIO(base64.b64decode(self._sample_font_str_))
22         )
23         self._font_ = ttLib.TTFont(
24             BytesIO(base64.b64decode(b64str))
25         )
26 
27     def parse_code(self, code):
28         code_uni = self._font_.getBestCmap().get(code, None)
29         if code_uni is None:
30             return chr(code) 
31         code_obj = self._font_['glyf'][code_uni]
32         for uni in self._sample_font_.getGlyphNames()[1:-1]:
33             if code_obj == self._sample_font_['glyf'][uni]:
34                 return self._glyph_map_.get(uni, '')
35         return chr(code)
36 
37     def parse_str(self, s):
38         res = ''
39         for c in s:
40             res += self.parse_code(ord(c))
41         return res
42 
43     

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:操作类型之字符串

下一篇:python生成器简单了解