解决猫眼网反爬虫策略的爬虫

项目代码:Github [目录]

一.引入问题

1

可以看到,猫眼网电影评分,票房等的数据在响应的html中并不是直接提供给你的。这里的xefcf,xef87等数据,是以‘特殊符号’的形式显示出来的。

2

可以发现这里请求了一个woff字体文件,而xefcf,xef87等数据的规则就是在这其中的。所以我们只需要在请求这个网页的同时,截去这部分style,然后获得woff地址,将它下载到本地,进行解析,就可以实现对评分的解密了。

但是再来看下面,当同一部电影的页面刷新时。

3


4

这里的评分编码改变了,下面请求的woff的url也改变了。所以每次请求电影页面使用的woff都不是同一个。

在这种情况下,如何才可以实现评分的爬取呢?

二.分步实现 1.页面爬取

第一步我们需要先将整个html页面获取,其中重要的数据就是评分所在的那个span,还有woff的url所在的那个style.

这里使用requests获取网页内容,用BeautifulSoup进行关键内容解析.

# 请求头设置 header = { 'Accept': '*/*;', 'Connection': 'keep-alive', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Host': 'maoyan.com', 'Referer': 'http://maoyan.com/', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36' } def web(url): db_data = requests.get(url, headers=header) # 这里直接将其编码之前部分替换掉,防止之后使用转义 soup = BeautifulSoup(db_data.text.replace("&#x",""), 'lxml') titles = soup.select( 'body > div.banner > div > div.celeInfo-right.clearfix > div.movie-stats-container > div > div > span > span') wotfs = soup.select('head > style') wotflist = str(wotfs[0]).split('\n') maoyanwotf就是当前页面所使用的woff地址了。 = wotflist[5].replace(' ','').replace('url(\'//','').replace('format(\'woff\');','').replace('\')','')

此时titles就是一个获取了评分span的list,当然它只有一个元素。

maoyanwotf就是当前页面所使用的woff地址了。

2.woff下载

上一步我们得到了maoyanwotf,其中是当前页面所使用的woff地址,所以接下来就要对这个url进行下载,保存到本地。

# 下载请求电影页面的woff字体到本地 def downfont(maoyanwotf): r = requests.get('http://'+maoyanwotf) with open("demo.woff", "wb") as code: code.write(r.content) font = TTFont("demo.woff") font.saveXML('to.xml')

这样就下载到了这次请求页面所用的woff了,保存为demo.woff。

3.字体解析规则

那么这个to.xml有什么用呢?

这就是我们在每次刷新都会改变woff的情况下,实现爬取的关键所在了。

font.saveXML('to.xml')就是将TTFont打开的woff转换为xml的形式,在xml中我们可以直接找到字体的相关数据,比如一个字符的笔画信息等。

来看一个字体xml文件的重要内容。完整内容参考:to.xml

<!--GlyphOrder 这个标签中就是这个字体xml包含的字符种类了,glyph00000和x这两个不用考虑 --> <GlyphOrder> <GlyphID/> <GlyphID/> <GlyphID/> <GlyphID/> .... <GlyphID/> <GlyphID/> <GlyphID/> </GlyphOrder> <!--glyf 这个标签中是这些字体的具体坐标画法,一个TTGlyph对应一个字体,而其中contour标签的坐标数据,就是唯一确定这个字体是什么的最好的确定方法--> <glyf> <TTGlyph/><!-- contains no outline data --> <TTGlyph xMin="0" yMin="-13" xMax="511" yMax="719"> <contour> <pt x="130" y="201" on="1"/> ... <pt x="42" y="189" on="1"/> </contour> <instructions/> </TTGlyph> ... ... <TTGlyph xMin="0" yMin="0" xMax="503" yMax="719"> <contour> <pt x="503" y="84" on="1"/> ... <pt x="152" y="84" on="1"/> </contour> <instructions/> </TTGlyph> </glyf> GlyphOrder 这个标签中就是这个字体xml包含的字符种类了,glyph00000和x这两个不用考虑。 glyf 这个标签中是这些字体的具体坐标画法,一个TTGlyph对应一个字体,而其中contour标签的坐标数据,就是唯一确定这个字体是什么的最好的确定方法。

所以可以得出结论,不管每次请求的woff怎么变,它里面的字符的contour标签内的坐标画法是不会改变的。

既然如此,我们只需要一个模板,在这个模板中,我们先手动解码一个充当模板的woff。

如何制作这样一个模板呢?

我们先来找一个woff和woff生成的xml,woff可以用字体查看器High-Logic FontCreator打开。效果如下。

6

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspwff.html