吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6084|回复: 16
上一主题 下一主题
收起左侧

[Python 原创] [爬虫--字体反爬] 爬取起点小说中文网的字数

  [复制链接]
跳转到指定楼层
楼主
hybpjx 发表于 2023-5-17 11:28 回帖奖励
本帖最后由 hybpjx 于 2023-5-17 11:37 编辑

字体加密

主要 难点为 字体TTF加密 需要 下载相应的包 然后做解析 对应的月票也是同理

其实非常简单

详细的教程直接看我的博客 https://www.cnblogs.com/zichliang/p/17408064.html
里面有详细的解释

下文直接贴代码
!!本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
下面贴上代码

# -*- coding: utf-8 -*-
# @Time    : 2022/6/30 11:21
# @Author  : lzc
# @Email   : hybpjx@163.com
# @File    : QiDianNovelPro.py
# @Software: PyCharm
import os
import random
import re
import time
from urllib.parse import urljoin
from fontTools.ttLib import TTFont
import fake_useragent
import requests
from lxml import etree

class QiDianNovel:
    def __init__(self):
        self.base_url = "https://www.qidian.com/all/"
        self.session = requests.Session()
        self.item = {}
        self.header = {
            "User-Agent": fake_useragent.UserAgent().random
        }
        self.font_dir_name = "font"
        self.fontSep = os.sep

    def fetch(self, url):
        response = self.session.get(url, headers=self.header)
        return response

    def parse_font(self, html):
        # 获得加密后的数字
        encrypted_number = re.findall('</style><span class=".*?">(.*?)</span>', html)
        # print(encrypted_number)
        # 利用正则获取动态url
        font_url = re.findall(r"format\('eot'\); src: url\('(.*?)'\) format\('woff'\)", html)[0]
        # 发送请求,下载字体加密文件
        font_response = self.fetch(font_url)

        jiami_font_file_name = self.font_dir_name + self.fontSep + "jiami.woff"
        # xml 解密的格式
        jiemi_font_file_name = self.font_dir_name + self.fontSep + "jiemi.xml"

        if not os.access(jiami_font_file_name, os.F_OK):
            os.mkdir("." + self.fontSep + self.font_dir_name)
        with open(jiami_font_file_name, 'wb')as f:
            f.write(font_response.content)
        # 解析字体解密文件 并且 创建TTFont对象
        font_obj = TTFont(jiami_font_file_name)

        # 转换成xml明文格式
        font_obj.saveXML(jiemi_font_file_name)
        mapping_dict = self.font_encode(encrypted_number, font_obj)
        # 通过匹配response去掉特殊符号的值 和 改成阿拉伯数字后的关系映射表,把密文改成明文  100196   = 3
        for i in encrypted_number:  # 去掉response去掉特殊符号的值[[],[],[]]
            # print(i)  #  ['100388', '100389', '100388', '100385', '100385']
            for index, num in enumerate(i):  # 100388
                # print(index,num)
                for k in mapping_dict:  # 改成阿拉伯数字后的关系映射表
                    # print(k)
                    if num == str(k):
                        i[index] = mapping_dict[k]
        # print("解析之后的月票数", encrypted_number)
        # 对单个明文进行拼接成完整的月票数
        list_ = []
        for i in encrypted_number:
            j = ''
            for k in i:
                j += k
            list_.append(j)
        return list_

    def font_encode(self, encrypted_number, font_obj):
        [i]"""
[i]        [b][i]:param[i] encrypted_number: [i]加密后的数字
[i]        [b][i]:param[i] font_obj: fontTools[i]对象
[i]        [b][i]:return[i]:
[i]        """
[i]        # 获取映射表
        mapping_dict = font_obj.getBestCmap()
        # print("字体加密映射表", mapping_dict)
        for index, i in enumerate(encrypted_number):
            new_font_list = re.findall(r'\d+', i)  # 去掉特殊符号 &#  &# ;
            encrypted_number[index] = new_font_list
        dict_e_a = {
            "one": '1', "two": '2',
            "three": '3', "four": '4',
            "five": "5", "six": '6',
            "seven": "7", "eight": '8',
            "nine": '9',
            "zero": '0', 'period': "."
        }
        for i in mapping_dict:
            # 遍历dict_e_a
            # print(i)
            for j in dict_e_a:
                # dict_的值等于dict_e_a的键
                if mapping_dict[i] == j:
                    mapping_dict[i] = dict_e_a[j]
        # print("替换成数字后的关系映射表", mapping_dict)
        return mapping_dict

    def get_data(self):
        # 解析 url
        html = self.fetch(self.base_url).text
        # tree对象 不解释
        # 拿到 字体列表
        font_list = self.parse_font(html)

        for index, font in (enumerate(font_list)):
            # 小说 字数
            self.item['novel_number'] = font + "万字"
            # 防止反爬,随即休眠12            time.sleep(random.randint(1, 2))
            print(self.item)

if __name__ == '__main__':
    QiDianNovel().get_data()

免费评分

参与人数 3吾爱币 +10 热心值 +3 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xuanshixh + 1 + 1 用心讨论,共获提升!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
ccskcq 发表于 2023-5-17 12:56
现在好看不懂,学习了。
3#
amwquhwqas128 发表于 2023-5-17 16:14
4#
abc023119 发表于 2023-5-17 16:28
5#
1225661221 发表于 2023-5-17 16:59
做小说网站的可能用的到
6#
wendao_lx 发表于 2023-5-17 17:22
这个可以有,收藏了
7#
hoochon 发表于 2023-5-17 18:49

学习一下
8#
hzxszxd 发表于 2023-5-17 20:54
学习了,多谢
9#
zhangmi008 发表于 2023-5-17 21:46
学习了,感谢
10#
Kabc123654 发表于 2023-5-22 14:10
学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 22:10

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表