Python爬虫进阶 | 某音字体反爬分析

字体反爬案例

爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用 python 爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码。这种一般是网站设置了字体反爬。

1. 准备url

网址: https://www.iesdouyin.com/share/user/88445518961

2. 获取数据 分析字体加密方式

任务:爬取个人信息展示页中的关注、粉丝人数和点赞数据,页面内容如图 下 所示。

在编写代码之前,我们需要确定目标数据的元素定位。定位时,我们在 HTML 中发现了一些奇怪的符号,HTML 代码如下:

页面中重要的数据都是一些奇怪的字符,本应该显示数字的地方在 HTML 中显示的是""。

要注意的是,Chrome 开发者工具的元素面板中显示的内容不一定是相应正文的原文,要想知道 "" 符号是什么,还需要到网页源代码中确认。对应的网页源代码如下:

</span><span class="follower block">
  <span class="num">
    <i class="icon iconfont follow-num">  </i>
    <i class="icon iconfont follow-num">  </i>
    <i class="icon iconfont follow-num">  </i>
    <i class="icon iconfont follow-num">  </i>.
    <i class="icon iconfont follow-num">  </i>w
  </span>
  <span class="text">粉丝</span>
</span>

抖音将这些数字的数据都做了字体进行映射,用了他们自己的字体,那我们可以看看开发者工具的 network 查看他所用的字体,一般都是 wolf 或者 ttf 结尾的,可以看到:

我们多刷新几次,发现一直访问的是这个字体文件:

https://s3.pstatp.com/ies/resource/falcon/douyin_falcon/static/font/iconfont_9eb9a50.woff

我们先把这个文件下载下来,font creator软件打开,也可以使用在线工具 https://font.qqe2.com/

看到这个图片我们就明白了字体与数字的关系

这个时候,需要大家安装pip install fontTools,使用fontTool打开ttf文件转化成xml文件

采用以下代码

from fontTools.ttLib import TTFont
font_1 = TTFont(‘douyin.ttf‘)
font_1.saveXML(‘font_1.xml‘)

这个就是我们需要找的映射,配合上面在 字体和数字的对应,一起用,这个就破解了。

3. 代码实现字体映射关系

关系映射表

regex_list = [
        {‘name‘: [‘0xe602‘, ‘0xe60e‘, ‘0xe618‘], ‘value‘: ‘1‘},
        {‘name‘: [‘0xe603‘, ‘0xe60d‘, ‘0xe616‘], ‘value‘: ‘0‘},
        {‘name‘: [‘0xe604‘, ‘0xe611‘, ‘0xe61a‘], ‘value‘: ‘3‘},
        {‘name‘: [‘0xe605‘, ‘0xe610‘, ‘0xe617‘], ‘value‘: ‘2‘},
        {‘name‘: [‘0xe606‘, ‘0xe60c‘, ‘0xe619‘], ‘value‘: ‘4‘},
        {‘name‘: [‘0xe607‘, ‘0xe60f‘, ‘0xe61b‘], ‘value‘: ‘5‘},
        {‘name‘: [‘0xe608‘, ‘0xe612‘, ‘0xe61f‘], ‘value‘: ‘6‘},
        {‘name‘: [‘0xe609‘, ‘0xe615‘, ‘0xe61e‘], ‘value‘: ‘9‘},
        {‘name‘: [‘0xe60a‘, ‘0xe613‘, ‘0xe61c‘], ‘value‘: ‘7‘},
        {‘name‘: [‘0xe60b‘, ‘0xe614‘, ‘0xe61d‘], ‘value‘: ‘8‘}
    ]

4. 完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import requests
from lxml import etree

start_url = ‘ https://www.iesdouyin.com/share/user/88445518961‘

def get_real_num(content):
    content = content.replace(‘ &#‘, ‘0‘).replace(‘; ‘, ‘‘)
    regex_list = [
        {‘name‘: [‘0xe602‘, ‘0xe60e‘, ‘0xe618‘], ‘value‘: ‘1‘},
        {‘name‘: [‘0xe603‘, ‘0xe60d‘, ‘0xe616‘], ‘value‘: ‘0‘},
        {‘name‘: [‘0xe604‘, ‘0xe611‘, ‘0xe61a‘], ‘value‘: ‘3‘},
        {‘name‘: [‘0xe605‘, ‘0xe610‘, ‘0xe617‘], ‘value‘: ‘2‘},
        {‘name‘: [‘0xe606‘, ‘0xe60c‘, ‘0xe619‘], ‘value‘: ‘4‘},
        {‘name‘: [‘0xe607‘, ‘0xe60f‘, ‘0xe61b‘], ‘value‘: ‘5‘},
        {‘name‘: [‘0xe608‘, ‘0xe612‘, ‘0xe61f‘], ‘value‘: ‘6‘},
        {‘name‘: [‘0xe609‘, ‘0xe615‘, ‘0xe61e‘], ‘value‘: ‘9‘},
        {‘name‘: [‘0xe60a‘, ‘0xe613‘, ‘0xe61c‘], ‘value‘: ‘7‘},
        {‘name‘: [‘0xe60b‘, ‘0xe614‘, ‘0xe61d‘], ‘value‘: ‘8‘}
    ]

    for i1 in regex_list:
        for font_code in i1[‘name‘]:
            content = re.sub(font_code, str(i1[‘value‘]), content)

    html = etree.HTML(content)
    douyin_info = {}
    # 获取抖音ID
    douyin_id = ‘‘.join(html.xpath("//div[@class=‘personal-card‘]/div[@class=‘info1‘]/p[@class=‘shortid‘]/text()"))
    douyin_id = douyin_id.replace(‘抖音ID:‘, ‘‘).replace(‘ ‘, ‘‘)
    i_id = ‘‘.join(html.xpath("//div[@class=‘personal-card‘]/div[@class=‘info1‘]/p[@class=‘shortid‘]/i/text()"))
    douyin_info[‘douyin_id‘] = str(douyin_id) + str(i_id)

    # 关注
    douyin_info[‘follow_count‘] = ‘‘.join(html.xpath(
        "//div[@class=‘personal-card‘]/div[@class=‘info2‘]/p[@class=‘follow-info‘]//span[@class=‘focus block‘]//i/text()"))
    # 粉丝
    fans_value = ‘‘.join(html.xpath(
        "//div[@class=‘personal-card‘]/div[@class=‘info2‘]/p[@class=‘follow-info‘]//span[@class=‘follower block‘]//i[@class=‘icon iconfont follow-num‘]/text()"))

    unit = html.xpath(
        "//div[@class=‘personal-card‘]/div[@class=‘info2‘]/p[@class=‘follow-info‘]//span[@class=‘follower block‘]/span[@class=‘num‘]/text()")
    if unit[-1].strip() == ‘w‘:
        douyin_info[‘fans‘] = str(float(fans_value) / 10) + ‘w‘
        fans_count = douyin_info[‘fans‘][:-1]
        fans_count = float(fans_count)
        fans_count = fans_count * 10000
        douyin_info[‘fans_count‘] = fans_count
    else:
        douyin_info[‘fans‘] = fans_value
        douyin_info[‘fans_count‘] = fans_value
    # 点赞
    like = ‘‘.join(html.xpath(
        "//div[@class=‘personal-card‘]/div[@class=‘info2‘]/p[@class=‘follow-info‘]//span[@class=‘liked-num block‘]//i[@class=‘icon iconfont follow-num‘]/text()"))
    unit = html.xpath(
        "//div[@class=‘personal-card‘]/div[@class=‘info2‘]/p[@class=‘follow-info‘]//span[@class=‘liked-num block‘]/span[@class=‘num‘]/text()")
    if unit[-1].strip() == ‘w‘:
        douyin_info[‘like‘] = str(float(like) / 10) + ‘w‘
        like_count = douyin_info[‘like‘][:-1]
        like_count = float(like_count)
        like_count = like_count * 10000
        douyin_info[‘like_count‘] = like_count
    else:
        douyin_info[‘like‘] = like
        douyin_info[‘like_count‘] = like

    # 作品
    worko_count = ‘‘.join(html.xpath("//div[@class=‘video-tab‘]/div/div[1]//i/text()"))
    douyin_info[‘work_count‘] = worko_count
    return douyin_info

def get_html():
    header = {
        ‘user-agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36‘
    }
    response = requests.get(url=start_url, headers=header, verify=False)
    return response.text

def run():
    content = get_html()
    info = get_real_num(content)
    print(info)

if __name__ == ‘__main__‘:
    run()

5. 结果

原文地址:https://blog.51cto.com/14205748/2474515

时间: 2024-10-07 04:03:05

Python爬虫进阶 | 某音字体反爬分析的相关文章

Python爬虫进阶 | 某监测平台数据加密逆向分析

今天带大家分析一下某建筑市场监管平台的数据加密 链接: aHR0cDovL2p6c2MubW9odXJkLmdvdi5jbi9kYXRhL2NvbXBhbnk= 点击企业查询, 发现返回的数据是经过加密后的数据 1. 寻找返回的数据 既然数据是通过这个 url 返回的, 全局搜索url http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=0&pgsz=15 尝试全局模糊搜索 /query/comp/list 点击

Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二

说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之间对抗. CSDN上关于汽车之家的反爬文章千千万万了,但是爬虫就是这点有意思,这一刻写完,下一刻还能不能用就不知道了,所以可以一直不断有人写下去.希望今天的博客能帮你学会一个反爬技巧. 今天要爬去的网页 https://car.autohome.com.cn/config/series/59.htm

python解析字体反爬

爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用python爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码.这种一般是网站设置了字体反爬 一.58同城 用谷歌浏览器打开58同城:https://sz.58.com/chuzu/,按F12用开发者模式查看网页源代码,可以看到有些房屋出租标题和月租是乱码,但是在网页上浏览却显示是正常的. 用python爬取下来也是乱码: 回到网页上,右键查看网页源代码,搜索font-face关键字,可以看到一大串用base64加密的字

Python爬虫进阶一之爬虫框架概述

综述 爬虫入门之后,我们有两条路可以走. 一个是继续深入学习,以及关于设计模式的一些知识,强化Python相关知识,自己动手造轮子,继续为自己的爬虫增加分布式,多线程等功能扩展.另一条路便是学习一些优秀的框架,先把这些框架用熟,可以确保能够应付一些基本的爬虫任务,也就是所谓的解决温饱问题,然后再深入学习它的源码等知识,进一步强化. 就个人而言,前一种方法其实就是自己动手造轮子,前人其实已经有了一些比较好的框架,可以直接拿来用,但是为了自己能够研究得更加深入和对爬虫有更全面的了解,自己动手去多做.

Python爬虫进阶二之PySpider框架安装配置

关于 首先,在此附上项目的地址,以及官方文档 PySpider 官方文档 安装 1. pip 首先确保你已经安装了pip,若没有安装,请参照 pip安装 2. phantomjs PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速.原生支持各种Web标准:DOM 处理.CSS 选择器.JSON.Canvas 和 SVG. PhantomJS 可以用于页面自动化.网络监测.网页截屏以及无界面测试等. 安装 以上附有官方安

Python爬虫进阶三之Scrapy框架安装配置

初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 Win7,首先,你要有Python,我用的是2.7.7版本,Python3相仿,只是一些源文件不同. 官网文档:http://doc.scrapy.org/en/latest/intro/install.html,最权威哒,下面是我的亲身体验过程. 1.安装Python 安装过程我就不多说啦,我的电

Python爬虫进阶五之多线程的用法

前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库.而多线程 thread 在 Python 里面被称作鸡肋的存在!而没错!本节介绍的是就是这个库 thread. 不建议你用这个,不过还是介绍下了,如果想看可以看看下面,不想浪费时间直接看 multiprocessing 多进程 鸡肋点 名言: "Pyt

(原)python爬虫入门(2)---排序爬取的辽宁科技大学热点新闻

发现科大网页的源码中还有文章的点击率,何不做一个文章点击率的降序排行.简单,前面入门(1)基本已经完成我们所要的功能了,本篇我们仅仅需要添加:一个通过正则获取文章点击率的数字:再加一个根据该数字的插入排序.ok,大功告成! 简单说一下本文插入排序的第一个循环,找到列表中最大的数,放到列表 0 的位置做观察哨. 上代码: # -*- coding: utf-8 -*- # 程序:爬取点击排名前十的科大热点新闻 # 版本:0.1 # 时间:2014.06.30 # 语言:python 2.7 #--

Python爬虫进阶之Scrapy框架安装配置

Python爬虫进阶之Scrapy框架安装配置 初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 Win7,首先,你要有Python,我用的是2.7.7版本,Python3相仿,只是一些源文件不同. 官网文档:http://doc.scrapy.org/en/latest/intro/install.html,最权威哒,下面是我的亲身体验过程. 1