58同城字体破解

网络爬虫 2019-01-10 971

58同城的其中一个反爬措施是字体反爬,如下图:

在租房详情页里面的大部分数字信息都设置了不同的字体。
1.解析出网页的字体文件
在网页中查找@font-face的部分,如下图:

使用以下代码将字体文件写入本地:
import base64

font_face = ""
b = base64.b64decode(font_face)
with open('ft.ttf', 'wb') as f:
f.write(b)

在将字体文件解析为xml:

from fontTools.ttLib import TTFont
font = TTFont('ft.ttf')
font.saveXML('ft.xml')

xml内容结构如下:

非Unicode显示
这是下载下的html文件中价格部分,其中价格被我标记了实际数字价格。

查找xml文件:

在xml的部分中,name与code对应,name与code对应与数字的关系是name的最后一位-1=实际数字----->网页中的code。

先将解析的文字使用Unicode加密,在对应解析出的xml文件就可以得到实际的数字了。

代码如下:

import base64  
from lxml import etree  
from fontTools.ttLib import TTFont  
import requests  
import re  
import functools

# 综合思想是  
headers = {  
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3573.0 Safari/537.36"  
}  

response = requests.get(url="https://bj.58.com/zufang/36724645212057x.shtml", headers=headers)  
text = response.text  
# print(text)  
price = etree.HTML(text)  
price = price.xpath('//*[@class="f36 strongbox"]/text()')[0]  
# 将网页中的乱码字符变为Unicode  
data = str(price.encode('unicode_escape')).strip("'").split(r'\\u')[1:]  
html = re.search(r'.*?<style>@font-face.*?base64,(.*?) format.*</style>.*', text, re.S)  
html = html.group(1).replace("')", '')  
b = base64.b64decode(html)  
with open('ft.ttf', 'wb') as f:  
    f.write(b)  
font = TTFont('ft.ttf')  
font.saveXML('ft.xml')  
with open('ft.xml', 'rb') as f:  
    x = f.read()  
    xml = etree.XML(x)  
    codes = []  
    names = []  
    for i in xml.xpath('//cmap/cmap_format_4[1]/map'):  
        code = i.xpath("@code")[0][2:]  
        name = i.xpath("@name")[0][-2:]  
        codes.append(code)  
        names.append(int(name)-1)  
    # 将xml中的code与name连接为一个字典型  
    dic_data = dict(zip(codes, names))  
    result_list = [dic_data[i] for i in data]  
    # 将列表中的数字变为一个整数字  
    result = functools.reduce(lambda x, y: x * 10 + y, result_list)  
    print(result)  

 

标签:网络爬虫

文章评论

评论列表

已有0条评论