python之requets+BeautifulSoup4破解58同城租房加密字体

介绍

58同城租房网页中,数字是加密的,如下图:

需要破解加密字体

加密字体文件

该加密字体文件,通过base64转码成字符串,包含在该网页的JavaScript代码中,如下图:

需要截取出该字符串,并做base64转码,成为普通的字体文件

完整代码

import requests,json,base64,io

from bs4 import BeautifulSoup
from io import BytesIO
from fontTools.ttLib import TTFont

headers={
    'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
    }

url='https://cc.58.com/chuzu/?PGTID=0d100000-0013-f33f-7673-74e19e2b0d2e&ClickID=4'



# 从html中截取base64 字体
def get_font_base64(html):
    start_pos=html.find("base64,")+len("base64,")
    end_pos=html.find("'",start_pos)
    res=html[  start_pos : end_pos ]

    return res

font_map={}

# 将base64格式的字符串进行解码,并读取字体文件信息,将映射关系放入到 font_map 中
def parse_font(font_base64):
    data=base64.b64decode(font_base64)
    # 从内存中加载字体文件
    f = BytesIO(data)
    font=TTFont(f)

    for key,value in font.getBestCmap().items():

        # 截取后2位(因为有10)
        n=int(value[-2:])-1
        # print(key,":",value,":",n)
        font_map[key]=n
    # print(data)

# 翻译,传入加密的数字字符串,返回明文
def decode(s):
    l=[]
    for item in s:
        if item==".":
            l.append(".")
            continue
        a=ord(item)
        # print("s:",s,"--a:",a)
        n=font_map[a]
        l.append(str(n))
    # 将list转换成字符串
    return "".join(l)



with requests.get(url,headers=headers) as resp:
    # 返回的文本内容,html
    # print(resp.text)
    # with open("/Users/mym/Desktop/58.html","wt") as f:
    #     f.write(resp.text)

    font_content=get_font_base64(resp.text)
    # print(font_content)
    parse_font(font_content)

    print(font_map)

    bs=BeautifulSoup(resp.text,"html.parser")
    # css选择器,查找所有的<li class="house-cell">标签
    # select() 返回list类型
    li_tags=bs.select("ul[class='house-list'] li[class='house-cell']")
    print("<li>标签的数量:",len(li_tags))

    for item in li_tags:
        """
        select_one()返回一个对象
        .text:返回标签中的文本内容
        strip():python字符串类中的,作用:去除前后空格
        """
        title=item.select_one("h2").text.strip()

        m=item.select_one("p[class='room']").text.strip()
        m=m[m.find(" "):-1].strip()

        # print(title,m,end=",")
        m2=decode(m)

        price=item.select_one("b[class='strongbox']").text.strip()
        price2=decode(price)
        print(title,",面积明文:",m2,",价格:",price2)

原文出处:/show_1EF6U3SDZIkm.html