前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python爬虫遇到字体反爬?教你搞定!

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

作者头像
快学Python
发布2021-08-09 14:55:06
5540
发布2021-08-09 14:55:06
举报
文章被收录于专栏:快学Python快学Python

人生苦短,快学Python

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

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

一、需求分析

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

部分网页源码展示:

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

二、发起请求

代码语言:javascript
复制
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第三方库查看字体文件:

代码语言:javascript
复制
from fontTools.ttLib import TTFont
font = TTFont('./f0a30a4dda64b4f8f344858115f54fc92296 (1).woff')
print(font.getGlyphOrder())

结果如下图所示:

代码语言:javascript
复制
['glyph00000', 'x', 'uniF4EF', 'uniF848', 'uniF88A', 'uniE7A1', 'uniE343', 'uniE137', 'uniF489', 'uniE5E2', 'uniF19B', 'uniE8CD']

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

代码语言:javascript
复制
.  # 对应网页中的9.2

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

四、数据抓取

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

代码语言:javascript
复制
import requests
import re
from fontTools.ttLib import TTFont

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

代码语言:javascript
复制
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、相关方法设置

发送请求获取相应

代码语言:javascript
复制
def get_html(self, url):
    response = requests.get(url, headers=self.headers)
    return response.content

处理字体文件

代码语言:javascript
复制
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

解析数据

代码语言:javascript
复制
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

正则匹配以及最终输出

代码语言:javascript
复制
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、最后运行:

代码语言:javascript
复制
if __name__ == '__main__':
    maoyan = MaoYan()
    maoyan.start_crawl()

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

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

五、小结

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

注意点:

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

最后,如果觉得今天的文章不错,就给右下角点个赞吧~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 快学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、需求分析
  • 二、发起请求
  • 三、替换规律
  • 四、数据抓取
  • 五、小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档