Python爬虫遇到字体反爬?教你轻松搞定!

Python实用宝典

共 5011字,需浏览 11分钟

 ·

2021-08-06 23:55


人生苦短,快学Python

大家在使用Python爬虫时,经常会遇到各种反爬问题。今天就以猫眼电影为例,看看如何解决其中的 字体反爬

由于对于一部电影来说,它的票房和评分数据是非常重要的,所以网站开发人员对它进行了保护,也就是字体反爬,今天的目标是破解猫眼电影网站的字体反爬。

一、需求分析

我们是需要爬取论坛文本数据,如下图所示:

部分网页源码展示:

我们发现数据是不在网页源码里面,而是以一种特殊的字符存在的。

二、发起请求

import requests
url = "https://maoyan.com/films/1298542"
headers = {
    "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
}
r = requests.get(url,headers=headers)
print(r.text)

然后得到如下数据(部分数据截图):

和网页源码里面的数据一样,通过requests简单请求之后发现评分,票房数据被特殊字符替换掉了,此时再次查看Elenments对应的标签里的数据,如下图所示:

由图可以发现有的字被替换掉了,所以我们需要找到数字被替换的方式(规律),然后替换回去。

三、替换规律

通过上面分可知,该网站中使用的字体对应的是stonefont,它是该网站为了反爬设置的自定义字体,它一定存在于style(样式)标签里面:

然后拿到url对应属性(xxx57..woff),它是不同于.ttf的字体文件,但是同样可以使用FontCreator打开:

//k3.autoimg.cn/g1/M02/D0/99/wKgHFVsUz1eAH_VRAABj9PS-ubk57..ttf

注意:如果该属性打不开文件,可以在属性前加上 https://maoyan.com

查看后发现是一个字体文件:

然后打开字体查看文件,把字体文件拖拽进去,如下图所示:(使用软件为FontCreator,可以查看字体的软件)

如果不想使用软件,可以打开百度字体平台网站,对应页面和软件打开是一样的

粗略一看其实发现不了什么,所以我们需要使用fontTools第三方库查看字体文件:

from fontTools.ttLib import TTFont
font = TTFont('./f0a30a4dda64b4f8f344858115f54fc92296 (1).woff')
print(font.getGlyphOrder())

结果如下图所示:

['glyph00000''x''uniF4EF''uniF848''uniF88A''uniE7A1''uniE343''uniE137''uniF489''uniE5E2''uniF19B''uniE8CD']

然后我们发现比如在先前的网页源码中发现的,

.  # 对应网页中的9.2

然后由此查看后缀,9----e7a1,在上图中

四、数据抓取

1、导包,我们使用re第三方库解析

import requests
import re
from fontTools.ttLib import TTFont

2、定制一个类(Maoyan),以及初始化属性设置:

class MaoYan(object):
    def __init__(self):
        self.url = 'https://maoyan.com/films/1298542'
        self.headers = {
            "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
        }
        self.font = TTFont('./f0a30a4dda64b4f8f344858115f54fc92296 (1).woff')
        self.numList = ['6''3''7''9''8''0''4''2''5']

3、相关方法设置

发送请求获取相应

def get_html(self, url):
    response = requests.get(url, headers=self.headers)
    return response.content

处理字体文件

def getNewList(self):
    newList = []
    glyList = self.font.getGlyphOrder()[2:]  # 前两个数据是没有用的,剔除
    for gly in glyList:
        m = gly.replace('uni''&#x').lower() + ';' # replace字符替换
        newList.append(m)

    return newList

解析数据

def parseData(self, data):
    for i in self.getNewList():
        if i in data:
            print(self.numList[self.getNewList().index(i)])
            data = data.replace(i, self.numList[self.getNewList().index(i)])

    return data

正则匹配以及最终输出

def start_crawl(self):
    html = self.get_html(self.url).decode('utf-8')
    # 正则匹配星级
    star = re.findall(r'<span class="index-left info-num ">\s+<span class="stonefont">(.*?)</span>\s+</span>', html)[0]
    print(star)
    star = self.parseData(star)

    print('用户评分: %s 星' % star)

4、最后运行:

if __name__ == '__main__':
    maoyan = MaoYan()
    maoyan.start_crawl()

结果如下,文字替换成功:

由于票房数据和这个评分有着异曲同工之妙,所以这里不再赘述,感兴趣的小伙伴可以去试一下。

五、小结

通常在2爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用 Python 爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码。这种一般是网站设置了字体反爬。字体反爬是一种比较常见的反爬方式,因为很多网站的文字信息是比较重要的,像是前面提到的猫眼电影电影票房评分等数据,非常重要,网站维护者当然会把这种数据进行反爬处理,只要好好分析,还是能够抓取到目标数据。

注意点:

  1. 字符匹配以及替换,还有正则表达式的书写规范
  2. 猫眼验证,当用户频繁的发起请求时,他会有一个验证,滑块验证,这个时候最好使用selenium手动操作一下,然后就可以正常的请求数据。


我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应红字验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

点击下方阅读原文可获得更好的阅读体验

Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报