url 数字 加密_python爬虫反反爬 | 像猫眼电影、大众点评等自定义 css 加密字体怎么破?...

479414ffe04f930c051f70fe31df2d0f.png

我们上次说了如何建立反反爬

当时还新建一个简单的帅b网页

具体可以戳以下链接

python爬虫反爬 | 对方是如何丧心病狂的通过 css 加密让你爬不到数据的

现在你已经知道了对方是

如何自定义字体加密的了

67a899276a8e3b229650b1fef46588cc.png

你要想去反反爬

你就要先站在对方的角度去思考问题

有句话这么说来着

“知己知彼,才能那啥”

01c9f7f889124aaeb4ce3b6bc28d5a9e.png

那么对于像猫眼电影、大众点评等等

那样的 css 自定义字体加密

应该怎么破呢?

接下来就是

学习 python 的正确姿势

dd3894db3a675a70fad9523344b8627d.png

有人说了

不就是把字体通过 unicode 编码吗?

fe8dc56ca16852280833e8ce764933dc.png

那就简单了啊

把每个字的编码找到

然后使用字典把编码和对应的字对应起来

抓取分析的时候

直接替换不就得了

f551f751d6a4092dc3671c3488700975.gif

有道理是有道理

但是

如果我每次返回给你的编码都不一样呢?

你说死不死

92a884b8e7fd4934c0c9cb77ce5c7895.png

好了好了,先别哭得那么舒服

我们来看看天猫电影票房榜单的页面

https://maoyan.com/board/1

16fa74c6269068eab8cb9bdeeca88ac2.png

25e7d16463a2080634b6768b61222a98.png

正如你所看到的那样

这里也使用了字体加密

通过源代码我们可以看到

font-face这里制定了字体文件路径

326ca4dfcb47fb15a34aab52cac81d01.png

还是熟悉的配方

熟悉的味道~

ef91bb29ee476397447802e8401688d4.png

不过小老弟

还是不要开心太早

刷新几次你就会发现

(盯着下图 2 秒钟)

32d106687c8d2cdaf37471c9d3f546d7.gif

看到没有

字体文件一直在变

woc!

玩呢?

85eb196f249fb12c2b3f06d9b08d2bff.png

720c4434dd07adb5f54ba89ee0e9d213.png

我们先把字体文件下载下来

# 把整个页面搞下来
url = 'https://maoyan.com/board/1'
html = download_html(url).decode('utf-8')

用正则把字体文件名拿一下

font_file_name = re.findall(r'//vfile.meituan.net/colorstone/(w+.woff)', html)[0]

拿到了文件名之后就构建一下url

然后把字体文件下载下来

url = 'http://vfile.meituan.net/colorstone/' + font_file_name
font_file = download_html(url)

接着把字体文件写到本地文件中

with open('fonts/' + font_file, 'wb') as f:
        f.write(new_file)

使用 fontTools 来获取字体

如果你之前没安装的话要安装才能用

接着我们把字体文件保存为 xml

font = TTFont('fonts/' + font_file)
font.saveXML('./'+font_file+'.xml')

d73be9b0650dd6ce9983a63c0d4cffda.png

快打开打开看看

6d98aca82af7a8db9e490dd82991bfc2.png

哇,这些玩意

有点眼熟啊

这不就是加密的 unicode 码么

左边的 id 难道就是对应的数字?

adea39024dcc3e0a9801c756efcb5f3c.png

没那么简单

就能找到聊得来的伴

尤其是在看过了那么多背叛

总是....

e0ac7b9075b0d692b971440f27e7af6f.png

不好意思

走错片场了

回到我们刚刚的 xml 文件

往下拉一下

可以看到这个

7cfb38f6147f2e0848ec494392ef3910.png

这里每一个编码都对应一个 TTGlyph 对象

从各种 x y 坐标可以猜测

它应该是用来绘制一个字的

我们把任意一个对象复制一下

然后用 matplotlib 根据坐标画个图试试看

import matplotlib.pyplot as plt
import re

str = """"
<contour>
        <pt x="130" y="201" on="1"/>
        <pt x="145" y="126" on="0"/>
        <pt x="216" y="60" on="0"/>
        <pt x="270" y="60" on="1"/>
        <pt x="332" y="60" on="0"/>
        <pt x="417" y="146" on="0"/>
        .....此处省略一点代码
      </contour>
"""


x = [int(i) for i in re.findall(r'<pt x="(.*?)" y=', str)]
y = [int(i) for i in re.findall(r'y="(.*?)" on=', str)]

print(x)
print(y)

plt.plot(x, y)
plt.show()

运行一波

374baf771958b8f64faed9b95a12f0c2.png


哈哈
妈的,uniEA78 就是 3 !
那么其它的编码也是这个道理了
还记得 python爬虫20 | 小帅b教你如何识别图片验证码 吗?
我们把那十个编码都画一遍
然后识别成数字
再封装成字典不就好了?

f56b99a952bfbd6a04fd5fc09ed273c0.png


好像这样做效率不高耶
有没有别的什么办法呢
我们再请求一下猫眼的字体文件
这次返回的文件又不同了

4472c0f687b3bf13602859adbf292b4e.png


打开你会发现
返回的编码都不一样了

84582093f2a0bc21350d91204f8565ff.png

3012ae87c0774b7f34cf2b95b3ad1ecd.png


咋整捏
还记得我们刚刚绘制的 3 么?

61f2dceb55801e50a8ac8927b5b26424.png


我们来搜一下新下载的文件
是不是绘制 3 的坐标也是一样的呢

39cd3f4848ebab288fd2dca9fcf13374.png


嘿嘿
仔细看下上面两张图里面的坐标
居然一模一样
也就是说
虽然编码的名称不同
但是
它们对象里面对应的内容是一样
对不对?
灵感来了
就是这里了
从这里下手

8a541fa2b47e765b8fa3cb924d6805a6.png


我们在第一次请求字体文件的时候
把编码对应的数字先给找出来
然后记下来
那么以后再请求到不同的字体文件的时候
虽然得到的编码不同
但是我们可以根据对象对应的内容进行判断
从而就可以得出新的编码和旧的编码指向同一个内容那么这两个编码对应的数字就是一样的

5daa8e476be848276207a1ce8d49d1d3.png


代码走起~
第一次请求获取一个字体文件

ab9abf811f43a1663847c3ef4f787528.png


打开 xml 获取到 unicode 编码
接着你可以通过绘制图的方式
或者通过 fontCreator 软件打开字体文件
或者通过字符去比对每个 unicode 代表的数字

d05b59485462afd2e4d00b3664a19662.png


然后
你就可以得到相应的数字
把它写到字典里面去

573e244e12010c45153b2859fe093f17.png


因为每次请求得到的字体编码都不同
所以上面这个就要作为我们的判断依据
当我们再请求的时候
如果得到的是和我们一开始请求
得到的字体文件一样的话
那就直接返回我们刚刚的字典

93ed17becbe3dc4adf53ed58c1fcd12a.png


不相同的话
我们就要把新的字体文件下载下来
然后对每个编码的对象跟旧的字体文件的每个编码的对象比较
如果对象是相同的话
就把旧的编码所对应的数字赋给新的编码
因为网页上显示的是 &#x 这样开头的
所以我们也要跟着换一下

6055951ba405b3e3b653e0d3ab28d80e.png


这时候运行
就会得到新的编码和对应的数字了

4472c0f687b3bf13602859adbf292b4e.png


爽啊
有了这个之后
我想爬取具体数据对你来说不在话下了吧
这里就随便获取一个电影的实时票房来举例

e8d554c5e4becddc25a6e76840ec1f00.png


简单粗暴的使用下正则

780a89ab3bdf454ede4f007a54145333.png


爬取到编码的时候我们转化一下
就是当编码和字典列表里面的编码有相同的
就替换成数字

01475e01607a28017161d7e74ab7a7a6.png


运行之后

c51d50cad0338172a2c32755713886bd.png


看下网页

562224fe80570fd56bf236d5e805eb62.png


没毛病
再爬取下总票房试试

0037f1620b307e5c8e49535073cd87d2.png


ok
依然没毛病

fa653f9a4f51cdb7407286b89c7f2be2.png

9cb92d6f739c044225ccb9927176af85.gif

扫一扫学习 Python 没烦恼

4fd30a5fc63fa1eda48dcbbad361106b.png

免责声明
以上内容仅为技术交流
请勿采集数据进行商用
否则后果自负
与帅b无关
下回见peace

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值