实战-快手H5字体反爬

前言

快手H5端的粉丝数是字体反爬,抓到的html文本是乱码 <SPAN STYLE='FONT-FAMILY: kwaiFont;'></SPAN> 可以看到对应的字体格式为 kwaiFont

经过一顿分析操作,发现每次返回的ttf文件内容每次都不太一样,无法自己做一份映射模板, 那么就不做模板了。可以通过OCR 或者 KNN 进行内容识别。本人采用 OCR 方式进行识别。这里推荐一个很吊的 OCRddddocr.

流程分析

  1. 找到对应ttf文件
  2. 分析ttf文件,将每个字体转换成图片
  3. 图片识别成文本
  4. 乱码映射

直接上代码

import re
import ddddocr
import requests
from lxml import etree
from io import BytesIO
from fontTools.ttLib import TTFont
from fontTools.pens.basePen import BasePen
from reportlab.graphics.shapes import Path
from reportlab.lib import colors
from reportlab.graphics import renderPM
from reportlab.graphics.shapes import Group, Drawing class ReportLabPen(BasePen):
"""
绘图
""" def __init__(self, glyph_set, path=None):
BasePen.__init__(self, glyph_set)
if path is None:
path = Path()
self.path = path def _moveTo(self, p):
(x, y) = p
self.path.moveTo(x, y) def _lineTo(self, p):
(x, y) = p
self.path.lineTo(x, y) def _curveToOne(self, p1, p2, p3):
(x1, y1) = p1
(x2, y2) = p2
(x3, y3) = p3
self.path.curveTo(x1, y1, x2, y2, x3, y3) def _closePath(self):
self.path.closePath() class KuaiShouSpider(object):
"""
快手爬虫
""" def __init__(self):
# OCR 识别类
self.ocr = ddddocr.DdddOcr() def ttf_2_word_map(self, ttf_content, fmt="png"):
"""
ttf内容转文本
:param ttf_content:
:param fmt:
:return:
"""
font = TTFont(BytesIO(ttf_content))
gs = font.getGlyphSet()
glyphNames = font.getGlyphNames() uniMap = font['cmap'].tables[0].ttFont.getBestCmap()
key_map = dict()
for k, v in uniMap.items():
key_map[v] = hex(k) data_dict = dict()
for i in glyphNames:
# 跳过'.notdef', '.null'
if i[0] == '.':
continue g = gs[i]
pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=5))
g.draw(pen)
w = 800
h = 800
g = Group(pen.path)
g.translate(0, 0) d = Drawing(w, h)
d.add(g)
img = renderPM.drawToString(d, fmt)
data = self.ocr.classification(img)
if data == '十':
data = '+'
elif data in [',', '。']:
data = '.'
key = key_map[i]
data_dict[key] = data return data_dict @staticmethod
def uni_code_2_word(uni_code, word_map):
"""
unicode 转 文本
:param uni_code:
:param word_map:
:return:
""" def _sub(num):
num = num.group()
num = re.findall(r'\d+', num)[0]
num = str(hex(int(num)))
return word_map[num] data = re.sub('&#(.+?);', _sub, uni_code) return data def get_user_info(self):
"""
获取用户数据
:return:
""" url = 'https://c.kuaishou.com/fw/user/ounixiong?fid=0&cc=share_copylink&followRefer=151&shareMethod=TOKEN&kpn=KUAISHOU&subBiz=PROFILE&shareId=16509009682073&shareToken=X-7IIolIHVVgN2bx&shareResourceType=PROFILE_OTHER&shareMode=APP&originShareId=16509009682073&appType=21&shareObjectId=136457866&shareUrlOpened=0&timestamp=1633759010452&captchaToken=HEADCgp6dC5jYXB0Y2hhEscCX569ztU1Y9XCAVp1Q5Rsm1H8fPYfPZBHvTyg5mwPyIQrJSR_j2mphorguzP9cB2sNWhg61OwW_LQEBvnHRS47j0GpmjIBOeqJ9j9kIbNTsXgNSQYZxkdToAm25EKa4ZLXOmE9ez5Bl-UMzRs4P2_g6SzI3fBs1yFvI7_eLd_yFogwimBE5eyopG9qDDm5lFPfSPm0GI6IhqLKpA1VBZd9cjZxsxq4jGlld1vYRxOFyfJis4oFSVM8fpDArN32KQ2pqejgjV8kK42jW-kpg4fl-1g5iWmqSczszEvEdB9s4l3QmQBfztuDSPbGf0yfY-whf93nOynaRmSeLH49sHSaPr_nwcGvjNjqeFdZoTpf2VBLV7mWvkVdthG0yV5Y6BqDPWSr57Js-dvLIcYlyq3gLbNxQOsulNch6o-HQ7dw2CZY006z-_eGhLniyxQb2WiE0ZVkCv0UGAb2gsoBTACTAIL' headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Cookie': 'did=web_232e842d3bcd4eceb358abfcf31ec030; didv=1634614098000; sid=e7921611a1cbb9669d28ce19; Hm_lvt_86a27b7db2c5c0ae37fee4a8a35033ee=1634614100; Hm_lpvt_86a27b7db2c5c0ae37fee4a8a35033ee=1634614104',
'DNT': '1',
'Host': 'c.kuaishou.com',
'Pragma': 'no-cache',
'Referer': 'https://c.kuaishou.com/fw/user/ounixiong?fid=0&cc=share_copylink&followRefer=151&shareMethod=TOKEN&kpn=KUAISHOU&subBiz=PROFILE&shareId=16509009682073&shareToken=X-7IIolIHVVgN2bx&shareResourceType=PROFILE_OTHER&shareMode=APP&originShareId=16509009682073&appType=21&shareObjectId=136457866&shareUrlOpened=0&timestamp=1633759010452',
'sec-ch-ua': '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"',
'sec-ch-ua-mobile': '?1',
'sec-ch-ua-platform': '"Android"',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Mobile Safari/537.36',
} response = requests.get(url, headers=headers) # 获取网页中的ttf文件
try:
ttf_file = re.findall(r'url\((https:.+?\.ttf)\)', response.text)[0]
except Exception as err:
print('网页访问异常')
return ttf_data = requests.get(ttf_file) ttf_word = self.ttf_2_word_map(ttf_data.content) # 解析
html = etree.HTML(response.text) fans_node = html.xpath('//span[contains(text(),"粉丝")]/preceding-sibling::span[1]')[0]
focus_node = html.xpath('//span[contains(text(),"关注")]/preceding-sibling::span[1]')[0]
fans = etree.tostring(fans_node).decode('utf-8')
focus = etree.tostring(focus_node).decode('utf-8')
fans = re.findall('>(.+?)<', fans)[0]
focus = re.findall('>(.+?)<', focus)[0]
fans = self.uni_code_2_word(fans, ttf_word)
focus = self.uni_code_2_word(focus, ttf_word)
print(fans)
print(focus) if __name__ == '__main__':
spider = KuaiShouSpider()
spider.get_user_info()

后记

可以考虑一下用 KNN的方式根据字体特征进行分类,准备好一些样本,进行训练.

实战-快手H5字体反爬的更多相关文章

  1. k 近邻算法解决字体反爬手段|效果非常好

    字体反爬,是一种利用 CSS 特性和浏览器渲染规则实现的反爬虫手段.其高明之处在于,就算借助(Selenium 套件.Puppeteer 和 Splash)等渲染工具也无法拿到真实的文字内容. 这种反 ...

  2. 网络字体反爬之pyspider爬取起点中文小说

    前几天跟同事聊到最近在看什么小说,想起之前看过一篇文章说的是网络十大水文,就想把起点上的小说信息爬一下,搞点可视化数据看看.这段时间正在看爬虫框架-pyspider,觉得这种网站用框架还是很方便的,所 ...

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

    说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之 ...

  4. Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇

    背景交代 在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术 ...

  5. Python爬虫实例:爬取猫眼电影——破解字体反爬

    字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...

  6. 58 字体反爬攻略 python3

    1.下载安装包 pip install fontTools 2.下载查看工具FontCreator 百度后一路傻瓜式安装即可 3.反爬虫机制 网页上看见的 后台源代码里面的 从上面可以看出,生这个字变 ...

  7. Python爬虫-字体反爬-猫眼国内票房榜

    偶然间知道到了字体反爬这个东西, 所以决定了解一下. 目标:  https://maoyan.com/board/1 问题: 类似下图中的票房数字无法获取, 直接复制粘贴的话会显示 □ 等无法识别的字 ...

  8. Spider-天眼查字体反爬

    字体反爬也就是自定义字体反爬,通过调用自定义的woff文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容! 1.思路 近期在爬取天 ...

  9. python解析字体反爬

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

随机推荐

  1. Python3-sqlalchemy-orm 分组统计

    #-*-coding:utf-8-*- #__author__ = "logan.xu" import sqlalchemy from sqlalchemy import crea ...

  2. redis未授权getshell的4种方式

    前言 redis未授权漏洞或弱口令一直是很有用的渗透突破口,最近正好闲的无事就拿redis来测试一些,做一个简单的收集,方便自己日后的回顾. 漏洞描述 Redis 默认情况下,会绑定在 0.0.0.0 ...

  3. MySQL实战45讲(10--15)-笔记

    11 | 怎么给字符串字段加索引? 维护一个支持邮箱登录的系统,用户表是这么定义的: mysql> create table SUser( ID bigint unsigned primary ...

  4. kubernetes 使用 PV 和 PVC 管理数据存储

    文章链接 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失--容器以干净的状态(镜像最初的状态)重 ...

  5. noip模拟39

    \(\color{white}{\mathbb{百般红紫博众爱,正是芳菲斗艳时,名之以:牡丹}}\) %%% szs巨佬AK \(t1\).\(t4\) 都会做,剩下两道好像都不太会,再次扫描到知识盲 ...

  6. error: object file .git/objects/...

    cd .git find . -type f -empty -delete -print tail -n 2 .git/logs/refs/heads/master git show xxxx(版本号 ...

  7. JS007. 深入探讨带浮点数运算丢失精度问题(二进制的浮点数存储方式)

    复现与概述 当JS在进行浮点数运算时可能产生丢失精度的情况: 从肉眼可见的程度上观察,发生精度丢失的浮点数是没有规律的,但该浮点数丢失精度的问题会100%复现.经查阅,这个问题要追溯至浮点数的二进制存 ...

  8. struts2执行流程和架构图

    一.struts2执行流程 二.架构图 只需要编写黄色部分的代码:

  9. Servlet3.0注解配置访问路径和urlParttern配置

    一.Servlet用注解配置访问路径 二.IDEA的tomcat相关配置 其中,第一点的配置文件,直接在IDEA的可视化操作界面修改就可以改掉配置文件中内容: 三.urlParttern配置 其中,* ...

  10. SpringBoot-异步定时-邮件任务

    目录 背景 异步任务 定时任务 邮件任务 背景 在我们的工作中,常常会用到异步处理任务,比如我们在网站上发送邮件, 后台会去发送邮件,此时前台会造成响应不动,直到邮件发送完毕,响应才会成功, 所以我们 ...