美文网首页反爬
字体反爬——python爬取大众点评数据2019-07-28 b

字体反爬——python爬取大众点评数据2019-07-28 b

作者: 夏海山 | 来源:发表于2019-07-28 03:09 被阅读0次

            寒暄一下,本人刚入门python不久,非常喜欢爬虫,平时没事儿的时候就喜欢研究一下,最近一个月一直在研究字体,想一步一步的把字体解析相关的知识都学一下,今天先分享一下研究了俩礼拜的字体反爬,代码结构写的比较初级,仅是交流,废话比较多,只是交流想法和经验,不喜勿喷。

            此前爬取大众点评的时候其实难度不大,xpath就能解决,从18年12月前后开始增加了字体的反爬,反爬技术更新了好几次,此前的就不写了,现在在研究最新的。如下仅供学习参考,不允许作为商业用途,内容为基本逻辑+局部代码,逻辑通了代码肯定是没问题的,知识得自己一点一点积累,大家加油吧。

            还有,这个脚本并不健壮,比如可能会存在list为空,读取值得时候报错的问题等,这些你自己加条件控制就好了,各有各的写法,大家好自珍重,健壮的脚本需要后续一点一点补充和维护。

            先贴结果镇楼

            {

            'address': '鼓楼东大街202号',

            'area': '南锣鼓巷/鼓楼东大街',

            'ave_price': '¥23',

            'fuwu': '8.8',

            'huanjing': '8.1',

            'kouwei': '9.1',

            'title': '杨记烤肉',

            'url': 'http://www.dianping.com/shop/22069001'

            }

    如下只介绍美食页的一页数据,例入:http://www.dianping.com/search/keyword/2/10_烤串

            如下粘贴的所有代码都是基于scrapy框架的,所以如果要用普通的xpath,请自己根据思路转换,还是那句话,多琢磨琢磨逻辑关系比粘来就用强千百倍。

    爬取思路:

    1、先贴引用的库,前两个是引用的scrapy的库,第三个是正则表达式,第四是requests,最后一个是字体的处理库。

    # -*- coding: utf-8 -*-

    import scrapy

    from dianping.items import DianpingItem

    import re

    import requests

    import json

    from fontTools.ttLib import TTFont

    2、读取页面源码,选取想要爬取的网页元素,使用xpath定位爬取;

    def parse(self, response):

            for each in response.xpath('//*[@id="shop-all-list"]/ul/li'):

            item = DianpingItem()

            item['title'] = each.xpath('div[2]/div[1]/a[1]/h4/text()').extract()[0]

            item['url'] = each.xpath('div[1]/a/@href').extract()[0]

            ……

    3、打印结果发现地址、商圈、客单价、评分位置打印出来的结果不完整,开发者工具选取位置看到如下图的格式,此时经过多方查找资料以后搞明白了这是一种字体反爬技术。页面通过css技术传入一组字体文件,这些字体文件都是提前通过字体软件裁剪好的文件,通过css将网页中的unicode的编码转换为指定的文字。如果不通过css转码,展示的效果就会如下图3-1所示。

    此处普及一个关于unicode的知识,就是操作系统、word和浏览器等之所以能够识别不同的字体文件中的文字,是因为他们所有的文字都用统一的unicode,所以电脑并不是读懂了文字,而是读懂了unicode,然后转换为了文字。字体反爬用到的字体包里的文字和unicode是不对应的,所以浏览器才会不识别,换言之就是说字体反爬使用的字体包中汉字对应的uniciode不是正常的真实的那个码,是程序员在unicode的后面找了一些码给硬安排上的,所以显示出来可能是个正常的不认识的符号或别国文字,或者索性就是框框。

    继续,此处接触问题的基本思路是找到字库文件,找到字库文件中unicode和汉字的对应关系,然后替换掉异常的unicode。

    (1)找到css的位置,如下图3-1地址位置有五个字是显示异常的,而且格式很一致,都使用css。如图3-2找到对应的css。

    图3-1 图3-2

    这块看不出来,直接对着页面右键查看源码,找到这个css,图3-3

    图3-3

    (2)打开这个css,内容如下:

    @font-face{font-family: "PingFangSC-Regular-shopNum";src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/620c796e.eot");src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/620c796e.eot?#iefix") format("embedded-opentype"),url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/620c796e.woff");} .shopNum{font-family: 'PingFangSC-Regular-shopNum';}@font-face{font-family: "PingFangSC-Regular-address";src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/e8ac2205.eot");src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/e8ac2205.eot?#iefix") format("embedded-opentype"),url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/e8ac2205.woff");} .address{font-family: 'PingFangSC-Regular-address';}@font-face{font-family: "PingFangSC-Regular-reviewTag";src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/8dae1f86.eot");src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/8dae1f86.eot?#iefix") format("embedded-opentype"),url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/8dae1f86.woff");} .reviewTag{font-family: 'PingFangSC-Regular-reviewTag';}@font-face{font-family: "PingFangSC-Regular-tagName";src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/ca8f6119.eot");src:url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/ca8f6119.eot?#iefix") format("embedded-opentype"),url("//s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/ca8f6119.woff");} .tagName{font-family: 'PingFangSC-Regular-tagName';}

    这块叨逼叨两句,如上每个json里都有好几个字体文件,这块是因为浏览器兼容的问题造成的,不知道原因的自行百度。

    尝试下载字体包,可以使用百度字体编辑器(http://fontstore.baidu.com/static/editor/index.html)打开,也可以使用fontcreator软件打开(如下图3-4是软件打开的效果)。

    图3-4

    打开以后我吓了一大跳,这个字体包字儿真多,一共603个,我下载了4个,此后又下了9个,发现都一样有603字,而每个字体包中字对应的unicode一般都不一样,此处留个梗,看下一段。

    css的地址会随时间变化,所以系统可能随机生成了很多字体包,每一个css中我们会发现是4组字体,在这块我大概停留了一个礼拜的时间,这个节点有几个思考和尝试,首先我们看到这个字体包是PingFangSC-Regular,我在思考是否可以直接用完整的字体包来解析,而省去找对应关系的尴尬,因为这块其实就是读取woff文件,然后找到字形相关的参数做对比,如果字形参数一致就认作是同一个字,然后返回最新的字和unicode对应关系,所以在这个节点上需要一个我们已知对应关系的字体库。而正常的字体库的汉字和unicode的对应关系是一定的,因此我自己还专门给自己建了一个unicode对照表……经过一番折腾以后发现……30多款pingfang字体库没有一个字体库里的汉字能够和下载下来的woff字形文件匹配的上!!!点评的程序员哥哥们做的有点绝了,所以我自己只能把603个字符和unicode的对应关系一个一个敲出来(一会附上)。

    第二个思考就是这个字体文件里都装些啥玩意,我该怎么处理这些信息并提炼出我想要的信息呢?查了大量资料,python用到了一个三方库fonttools,先把woff或者ttf文件转化为xml,打开xml会发现字体文件其实都是一些对应关系,自己找个工具动动手自己解析看看,我们能用到的就是unicode和对应的字形信息,所谓字形信息像是一些坐标,一些工具读出来可能就是个汉字或者汉字图,至于怎么读并不重要,c或者java应该都能实现,这个也是我后续研究的课题,暂时略过,你们自己再pycharm上调用fonttools库,引用的时候会自己弹出来一堆函数,可以挨个试试得出来的结果,我就是这么自己琢磨的,我使用fonttools 主要是干两件事1是找到unicode,2是找到unicode对应的字形信息。

    (3)使用正则表达式提取woff链接

    如下是代码(获取css、下载和解析woff)

    def parse(self, response):

            #print(response.text)

            #正则表达式获取css链接

            css_url="http:" + re.findall(r'(//.+svgtext.+\.css)',response.body.decode('utf-8'))[0]

            #css_url="http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/c6477fbab101bee5040777e08a62e13c.css"

            #print(css_url)

            css_res = requests.get(css_url).text

            #print(css_res)

            #print(css_res)

            #正则表达式获取class信息和url

            font_infos = re.findall('@font-face\{(.*?)\}', css_res)

            # print(font_infos)

            json_woff = {}

            for font_info in font_infos:

                    # print(font_info)

                    font_family = re.findall('font-family: "(.*?)";src', font_info, re.S)[0]

                    font_type = re.findall('.*-([^-]*)";src', font_info, re.S)[0]

                    woff_url ="http:" + re.findall('\),url\("(.*?)"\);', font_info, re.S)[0]

                    woff_name = re.findall('[^/]+(?!.*/)', woff_url, re.S)[0]

                    #print(font_family, font_type, woff_url, woff_name)

                    #将解析后的url读取存在本地,并将对应关系存入json

                    path ="D:\\mywork\\project\\dianping\\dianping\\font\\" + woff_name

                    r = requests.get(woff_url)

                    with open(path, "wb")as f:

                        f.write(r.content)

                        f.close()

                    json_woff[font_type] = path

                    #print(json_woff)

                    #如下是分类处理字体文件找到unicode和字符的最新对照,后面会有parse_font的内容。

                    address_temp = font_tool.parse_font(json_woff['address'])

                    shopNum_temp = font_tool.parse_font(json_woff['shopNum'])

                    reviewTag_temp = font_tool.parse_font(json_woff['reviewTag'])

                    tagName_temp = font_tool.parse_font(json_woff['tagName'])

    4、处理woff字体文件

    这块信息量非常大,逻辑简述一下

    (1)找一个已经下载的woff作为基础库,然后用软件打开人工一个一个敲出来unicode和字符的对应关系,按照对应顺序做俩list,把这些信息都放进去;

    # 读取文件名与css名称做匹配

    baseFonts = TTFont("D:\\mywork\\project\\dianping\\dianping\\font\\" +"first" +".woff")

    uni_num = ['unied61', 'unie6a6', 'unie001', 'unie621', 'unie5b0', 'unif4d1', 'unie1be', 'unif274', 'unif46d',

              'uniefeb', 'uniebb0', 'unie2d2', 'unie964', 'unie878', 'unie667', 'unie8bf', 'uniea3c', 'unie6f5',

              'unie4f0', 'unif6d7', 'unieffd', 'unie13f', 'unif843', 'unie184', 'unie2a9', 'unif723', 'unie683',

              'unif3a3', 'uniee31', 'unif345', 'unie0c8', 'unie919', 'unie9dd', 'unif2b6', 'unif113', 'unif313',

              'unie01e', 'unie4db', 'unie5e9', 'unie42a', 'unif13f', 'unif064', 'unie443', 'uniebfb', 'unie832',

              'uniefa3', 'unif01b', 'unie6be', 'unif885', 'unie455', 'unif434', 'unif6f8', 'unif68f', 'uniee42',

              'unif355', 'unie7c0', 'unif70d', 'unie67d', 'uniebcc', 'unie70c', 'unieddd', 'unie34c', 'unie0b7',

              'unie61e', 'unif65c', 'unie0b0', 'unie1c6', 'unif19e', 'unie19d', 'unif06e', 'unif846', 'unieb78',

              'uniee32', 'unie5a1', 'uniedba', 'unie2bf', 'unief45', 'unie567', 'unie821', 'unie754', 'unie387',

              'unif4bc', 'unied86', 'unie6f4', 'unif8d3', 'unie93a', 'uniea13', 'uniee66', 'unif361', 'uniecbf',

              'unif4d5', 'unif5ef', 'unie4b9', 'unie132', 'unif889', 'uniec13', 'unie65d', 'unif711', 'unie923',

              'uniede0', 'unie54b', 'unief3f', 'unie3d7', 'unie1dc', 'unif09c', 'unie363', 'unie105', 'unie5c4',

              'unieda4', 'uniefe4', 'unie20d', 'unie3cc', 'unie7bf', 'unie61d', 'unif573', 'unie4d6', 'unie52c',

              'unif89e', 'unie84d', 'unie682', 'unie4c1', 'unie7a9', 'unie2de', 'unie03a', 'unif607', 'unif161',

              'uniea8b', 'unied77', 'unif737', 'unif6e2', 'unif76e', 'unif181', 'unieb64', 'unieff3', 'unif0de',

              'unie052', 'unif74c', 'unie580', 'uniedeb', 'unif767', 'unieea9', 'unif016', 'unied74', 'unif483',

              'unieb44', 'unif19a', 'unieabb', 'unie8ae', 'unie6ed', 'unie223', 'unie5b8', 'unie59d', 'unie1bb',

              'unie4f2', 'unie992', 'unie0a9', 'uniea6e', 'unied2d', 'unie41c', 'uniee20', 'unie1a0', 'unif670',

              'unie6cd', 'unie570', 'unie357', 'unif71b', 'unif11c', 'unie034', 'unif029', 'unif3c7', 'unie938',

              'unie173', 'unie0a1', 'unie5b7', 'unif353', 'unie413', 'unie8a2', 'unif32a', 'unif30b', 'uniefc7',

              'unie66d', 'unieaf9', 'unie43a', 'unie677', 'unie328', 'unif0c1', 'unie451', 'unif1ea', 'unif035',

              'unie0e9', 'unie932', 'unie545', 'uniea1e', 'unie800', 'unif5b0', 'unie71c', 'unif31f', 'unif684',

              'unif481', 'uniec32', 'unif504', 'unieb13', 'unieb3d', 'unif014', 'unif873', 'unif5ba', 'unif79b',

              'unie804', 'unie39e', 'unied9c', 'unif357', 'unie6c9', 'unie98c', 'uniec38', 'unie41d', 'unif4ec',

              'unif0b3', 'unif5cc', 'uniea87', 'unie399', 'unif7ba', 'unif0ab', 'unieaef', 'unie537', 'unif808',

              'unief25', 'unif4e4', 'uniecef', 'unif725', 'unieca2', 'unie2e7', 'unif67b', 'unif230', 'unie2cd',

              'uniefc8', 'unif44d', 'uniee34', 'unif726', 'unie325', 'unif775', 'unieed0', 'unie7ae', 'unie469',

              'unif207', 'unieb9c', 'unif5fa', 'unie765', 'unif092', 'unie4e9', 'unie38b', 'unie649', 'unief42',

              'unie706', 'uniefdd', 'unie2d1', 'unied57', 'unif0c9', 'unie4ba', 'unie795', 'unie4e1', 'unie0ef',

              'unie653', 'unie4b2', 'unif123', 'unieff7', 'unif4d6', 'unieda3', 'unif6e4', 'unie613', 'unif7cc',

              'unie685', 'unieafc', 'unif32c', 'unie0f4', 'uniec8a', 'unif42b', 'unie09b', 'uniea20', 'unied6e',

              'unie098', 'unie68d', 'unieb3e', 'unie867', 'unif307', 'unif85f', 'unie7cd', 'unie0af', 'unif6da',

              'uniea55', 'unie0ca', 'unif636', 'unif152', 'unif7e1', 'unie85d', 'unif2ff', 'unie436', 'unie278',

              'unie6d9', 'unie0d5', 'unie99d', 'unif827', 'unie761', 'unif344', 'unif640', 'unie030', 'unie06d',

              'unie02f', 'unie3cd', 'unie2cb', 'unie7a6', 'unie5f3', 'unieca8', 'unif55b', 'unieddb', 'unif86d',

              'unieb40', 'unieabf', 'unif241', 'unief05', 'uniefcb', 'unie82c', 'unied15', 'unie7ff', 'unif285',

              'unie8c2', 'unif639', 'unie70b', 'unif1c7', 'unif44f', 'unif093', 'unief15', 'uniefd5', 'unif3f5',

              'unief50', 'unie064', 'unif84f', 'uniee97', 'unif8f9', 'unie033', 'unie9be', 'unif63f', 'uniea6f',

              'unif884', 'unie943', 'unieafb', 'unif267', 'unif2d7', 'unif0da', 'unie3eb', 'uniecea', 'unif55a',

              'uniee99', 'unie10c', 'unie4f8', 'unif047', 'uniefb8', 'unif4cd', 'unie448', 'unie078', 'unif336',

              'unie0cf', 'unieab1', 'unie3ca', 'unieee7', 'uniebd3', 'uniedf0', 'unied4c', 'unie6ae', 'unief38',

              'unie23d', 'unied99', 'unie42d', 'unif82b', 'unie8d9', 'unie0bf', 'unie79e', 'unie047', 'unif18d',

              'uniebfc', 'unieaf3', 'unie89c', 'unif374', 'unie178', 'unie6b4', 'unie591', 'unie7eb', 'uniead8',

              'unif34e', 'unie1ce', 'unieb36', 'unif119', 'uniefd6', 'unie8ed', 'unie33e', 'unied09', 'unie17a',

              'unif820', 'unif293', 'unied0b', 'unie8a7', 'unif426', 'unif37f', 'unif1c6', 'unie93d', 'unif7bb',

              'unie5c7', 'unif449', 'unif87e', 'unie782', 'unie138', 'unif747', 'unie1cb', 'unif543', 'unie4a1',

              'unif34f', 'unie929', 'unie4a8', 'unif6dc', 'unie8fc', 'unif155', 'unief54', 'unie7f1', 'unie7af',

              'unif303', 'unif6ae', 'unif33f', 'uniec80', 'uniecc7', 'unie6d0', 'uniefc6', 'unie8e8', 'unie828',

              'unie585', 'unie35e', 'unie391', 'unie342', 'unif789', 'unif6d8', 'unie426', 'uniecc6', 'unif4e3',

              'unif6c9', 'unif1e2', 'unif5b7', 'unif53e', 'unif7ec', 'unif317', 'unie51f', 'unie30e', 'unieaf6',

              'unif25a', 'unif061', 'unif581', 'unif66a', 'unied62', 'unif0ad', 'unie7d2', 'unief67', 'unie799',

              'unif036', 'unie3b3', 'unie83d', 'unif44c', 'unie356', 'unieba0', 'unie3c3', 'unief95', 'unie1cd',

              'unie3db', 'unif23d', 'unie160', 'uniea5a', 'unif56b', 'unif309', 'uniede3', 'unie039', 'unif7be',

              'unie33c', 'unif6c5', 'unied12', 'unie51d', 'unif6b8', 'unie986', 'uniec1e', 'unif09e', 'unif578',

              'unie9bf', 'unie463', 'unie9f9', 'unif2d0', 'unieb55', 'unief2e', 'uniea44', 'unie6fa', 'unif563',

              'unif0e8', 'unif814', 'unieee0', 'unif8ed', 'uniee64', 'unie57b', 'unie565', 'unie5be', 'unif0d6',

              'unie161', 'unif89a', 'unieeaa', 'unied9a', 'unie3a9', 'unie967', 'unie5b2', 'unif675', 'unif3e7',

              'unief9c', 'unie53c', 'unif565', 'unie54c', 'unie501', 'unie6c7', 'unif35c', 'unie7b2', 'unif654',

              'unif6f5', 'unie796', 'uniedac', 'unie388', 'unif149', 'unie069', 'unief1a', 'unif38b', 'uniea08',

              'unif2f7', 'unif52d', 'unie770', 'uniec96', 'uniec09', 'unie121', 'unie053', 'uniee24', 'unie1b9',

              'unif739', 'unie020', 'unif146', 'uniee51', 'uniedef', 'unie956', 'unieaa1', 'unie548', 'unif304',

              'uniea56', 'unie83c', 'unie3bf', 'unie137', 'unif188', 'uniea4d', 'unif421', 'unif30f', 'unie499',

              'unie244', 'unie7f9', 'unif350', 'unie352', 'unif84c', 'unie256', 'unie58f', 'unieda2', 'unieab4',

              'unif390', 'unie60b', 'unie0be', 'unie72a', 'uniea57', 'unif67a', 'unie280', 'unie1d1', 'uniedbf',

              'unif007', 'unie3e8', 'unie9cf', 'unie616', 'uniee5b', 'unie51a', 'unif5e1', 'unif442', 'unie419',

              'unif89f', 'unif5c7', 'unif6e6', 'unie37f', 'unie4c6', 'unieb7b', 'unif283', 'uniea71', 'unie7de',

              'unif4b1', 'unie6e7', 'unie2d7', 'unie575', 'uniee71', 'unief31', 'unie273']

    uni_name = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '店', '中', '美', '家', '馆', '小', '车', '大', '市', '公',

                '酒', '行', '国', '品', '发', '电', '金', '心', '业', '商', '司', '超', '生', '装', '园', '场', '食', '有', '新', '限',

                '天',

                '面', '工', '服', '海', '华', '水', '房', '饰', '城', '乐', '汽', '香', '部', '利', '子', '老', '艺', '花', '专', '东',

                '肉',

                '菜', '学', '福', '饭', '人', '百', '餐', '茶', '务', '通', '味', '所', '山', '区', '门', '药', '银', '农', '龙', '停',

                '尚',

                '安', '广', '鑫', '一', '容', '动', '南', '具', '源', '兴', '鲜', '记', '时', '机', '烤', '文', '康', '信', '果', '阳',

                '理',

                '锅', '宝', '达', '地', '儿', '衣', '特', '产', '西', '批', '坊', '州', '牛', '佳', '化', '五', '米', '修', '爱', '北',

                '养',

                '卖', '建', '材', '三', '会', '鸡', '室', '红', '站', '德', '王', '光', '名', '丽', '油', '院', '堂', '烧', '江', '社',

                '合',

                '星', '货', '型', '村', '自', '科', '快', '便', '日', '民', '营', '和', '活', '童', '明', '器', '烟', '育', '宾', '精',

                '屋',

                '经', '居', '庄', '石', '顺', '林', '尔', '县', '手', '厅', '销', '用', '好', '客', '火', '雅', '盛', '体', '旅', '之',

                '鞋',

                '辣', '作', '粉', '包', '楼', '校', '鱼', '平', '彩', '上', '吧', '保', '永', '万', '物', '教', '吃', '设', '医', '正',

                '造',

                '丰', '健', '点', '汤', '网', '庆', '技', '斯', '洗', '料', '配', '汇', '木', '缘', '加', '麻', '联', '卫', '川', '泰',

                '色',

                '世', '方', '寓', '风', '幼', '羊', '烫', '来', '高', '厂', '兰', '阿', '贝', '皮', '全', '女', '拉', '成', '云', '维',

                '贸',

                '道', '术', '运', '都', '口', '博', '河', '瑞', '宏', '京', '际', '路', '祥', '青', '镇', '厨', '培', '力', '惠', '连',

                '马',

                '鸿', '钢', '训', '影', '甲', '助', '窗', '布', '富', '牌', '头', '四', '多', '妆', '吉', '苑', '沙', '恒', '隆', '春',

                '干',

                '饼', '氏', '里', '二', '管', '诚', '制', '售', '嘉', '长', '轩', '杂', '副', '清', '计', '黄', '训', '太', '鸭', '号',

                '街',

                '交', '与', '叉', '附', '近', '层', '旁', '对', '巷', '栋', '环', '省', '桥', '湖', '段', '乡', '厦', '府', '铺', '内',

                '侧',

                '元', '购', '前', '幢', '滨', '处', '向', '座', '下', '県', '凤', '港', '开', '关', '景', '泉', '塘', '放', '昌', '线',

                '湾',

                '政', '步', '宁', '解', '白', '田', '町', '溪', '十', '八', '古', '双', '胜', '本', '单', '同', '九', '迎', '第', '台',

                '玉',

                '锦', '底', '后', '七', '斜', '期', '武', '岭', '松', '角', '纪', '朝', '峰', '六', '振', '珠', '局', '岗', '洲', '横',

                '边',

                '济', '井', '办', '汉', '代', '临', '弄', '团', '外', '塔', '杨', '铁', '浦', '字', '年', '岛', '陵', '原', '梅', '进',

                '荣',

                '友', '虹', '央', '桂', '沿', '事', '津', '凯', '莲', '丁', '秀', '柳', '集', '紫', '旗', '张', '谷', '的', '是', '不',

                '了',

                '很', '还', '个', '也', '这', '我', '就', '在', '以', '可', '到', '错', '没', '去', '过', '感', '次', '要', '比', '觉',

                '看',

                '得', '说', '常', '真', '们', '但', '最', '喜', '哈', '么', '别', '位', '能', '较', '境', '非', '为', '欢', '然', '他',

                '挺',

                '着', '价', '那', '意', '种', '想', '出', '员', '两', '推', '做', '排', '实', '分', '间', '甜', '度', '起', '满', '给',

                '热',

                '完', '格', '荐', '喝', '等', '其', '再', '几', '只', '现', '朋', '候', '样', '直', '而', '买', '于', '般', '豆', '量',

                '选',

                '奶', '打', '每', '评', '少', '算', '又', '因', '情', '找', '些', '份', '置', '适', '什', '蛋', '师', '气', '你', '姐',

                '棒',

                '试', '总', '定', '啊', '足', '级', '整', '带', '虾', '如', '态', '且', '尝', '主', '话', '强', '当', '更', '板', '知',

                '己',

                '无', '酸', '让', '入', '啦', '式', '笑', '赞', '片', '酱', '差', '像', '提', '队', '走', '嫩', '才', '刚', '午', '接',

                '重',

                '串', '回', '晚', '微', '周', '值', '费', '性', '桌', '拍', '跟', '块', '调', '糕']

    (2)把此后下载的任意一个woff字库打开后去跟基础库做信息比对,比对两个库中字形信息完全一致的那个unicode,利用unicode反向去list中找对应的字符,最终把最新的对应关系存成json。

    #此处online是最新下载的woff,base是基础库

    onlineFonts = TTFont(online_dir)

    #这块自己多print,这里baseFonts.getGlyphNames()是获取的woff中去除第一个和最后一个的所有字符信息,第一个和最后一个都没啥用

    base_glyphNames = baseFonts.getGlyphNames()[1:-1]

    online_glyphNames = onlineFonts.getGlyphNames()[1:-1]

    temp = {}

    #通过计算基础list的长度来计算循环次数

    a =len(uni_num)

    for i in range(0, a):

            for j in range(0, a):

                    #这里在比对字形是否一致

                    if onlineFonts['glyf'][online_glyphNames[i]] == baseFonts['glyf'][base_glyphNames[j]]:

                          #这里在遍历list找到base_glyphNames[j]对应的unicode对应的k           

                            for k in range(0,a):

                                    if uni_num[k]==base_glyphNames[j]:

                                            temp["u" + online_glyphNames[i][3:].lower()] = uni_name[k]

                                    else:

                                            pass

                      else:

                                pass

    5、字体替换

    这里有个坑,就是头上带“\u”的unicode,用print打印以后都会被转译,最终要么就成空白,要么就是其他的字儿。这里如果不想被转译,那就将存储unicode的list直接转化为字符串,然后用正则表达式把unicode 提取出来即可。

    以地址信息为例,直接贴代码

    #---------------------------------------地址------------------------------------------------------

    #这里返回的是一个list,内容自行打印,直接字符串化

    addresses=str(each.xpath('div[2]/div[3]/span').extract()[0])

    address_list=re.findall('\>(.*?)\<',addresses, re.S)

    #这里在获取最新address对应的json的key的list

    address_key=list(address_temp.keys())

    address_list =str(address_list)

    address =""

    for m in re.findall("'(.*?)'", address_list, re.S):

            #print(m)

            address_info =str(m.replace("\\", ""))

            if address_info  =="":

                    pass

            elif address_info in address_key:

                  address = address + address_temp[address_info]

            else:

                    address = address + address_info

            #print(address)

            item['address'] =address

    这里面太多细节了,我把我的坑基本都说了,其他的东西大家自己领悟吧。

    相关文章

      网友评论

        本文标题:字体反爬——python爬取大众点评数据2019-07-28 b

        本文链接:https://www.haomeiwen.com/subject/bylyrctx.html