Python3 selenium获取起点收藏榜单Top100并解析字体加密

news/2024/7/19 10:51:30 标签: 加密解密, selenium, 爬虫

1、爬虫简介

使用selenium模块获取起点中文作品书架作品排行,并打印相关的排行信息。

2、站点分析

需要爬取的内容

VIP收藏榜共5页,每一页展示的有20条排名数据,爬取完每一页的数据之后,自动点击下一页爬取,我们需要获取的内容有:

  • 排名
  • 书名
  • 作者
  • 收藏
    在这里插入图片描述

3、代码实现

# coding=utf-8
from selenium import webdriver
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from urllib.parse import urljoin
from selenium.common.exceptions import NoSuchElementException


class VipCollection:
    def __init__(self):
        self.driver = webdriver.Chrome(
            executable_path=r"C:\Users\Administrator\AppData\Local\Google Chrome\Chromebin\chromedriver.exe")
        self.start_url = "https://www.qidian.com/rank/vipcollect?style=1&page=1"

    # 打开VIP收藏榜网页
    def start(self):
        self.driver.get(self.start_url)
        self.driver.maximize_window()

    def page_request(self):
        try:
            wait = WebDriverWait(self.driver, 10)  # 设置网页加载超时时间10s
            wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'rank-body')))  # 等待页面排行数据被加载完成
            lis = self.driver.find_elements_by_xpath('''//*[@class='book-img-text']/ul/li''')  # 小说排名列表信息
            # 解析列表信息,获取小说名称、url、排名、收藏数
            for li in lis:
                data_rid = li.get_attribute('data-rid')  # 直接获取li标签的data-rid属性,即每一页的排名1,2,3,4...20
                page = int(self.driver.current_url.split('page')[-1][1:])  # 获取页码
                rank = (page - 1) * 20 + int(data_rid)  # 因为每一页的排名都是1、2、3、4、5...20,所以我们需要给排名进行计算
                name = li.find_element_by_xpath("./div[@class='book-mid-info']/h4/a").text  # 获取小说名称
                author = li.find_element_by_xpath("./div[@class='book-mid-info']/p[@class='author']/a[@class='name']").text  # 获取小说作者
                href = li.find_element_by_xpath("./div[@class='book-mid-info']/h4/a").get_attribute('href')
                detail_url = urljoin(self.start_url, href)  # 对url进行自动拼接,得到完整的小说详情url
                collection = li.find_element_by_xpath("./div[3]/div/p/span/span").text  # 获取收藏数
                print({'rank': rank, 'name': name, "author":author, 'detail_url': detail_url, 'collection': collection})

            # 定位下一页按钮,尝试点击元素直到最后一页
            try:
                pagenation = self.driver.find_element_by_xpath(
                    "//ul[@class='lbf-pagination-item-list']/li/a[@class='lbf-pagination-next ']")
                if pagenation:
                    pagenation.click()
                    self.page_request()  # 请求自己对页面进行解析
            # 下一页元素不存在就捕获异常,并结束
            except NoSuchElementException:
                print('已经是最后一页,等待5秒结束......')
        except Exception as e:
            print(e)

    # 等待5秒关闭浏览器
    def close(self):
        time.sleep(5)
        self.driver.close()


if __name__ == '__main__':
    top = VipCollection()
    top.start()
    top.page_request()
    top.close()

代码执行过程…
在这里插入图片描述

4、字体加密分析

从上面的代码执行结果我们可以看到,打印结果的collection书籍收藏数都是乱码的,是因为字体被加密的缘故,我们无法直接获取加密后的内容,这个在网页的源代码中也可以看出来,如下所示:
在这里插入图片描述
我们打开浏览器网页的源码,发现对应的是这串代码

 <p><span><style>@font-face { font-family: mflgGAGq; src: url('https://qidian.gtimg.com/qd_anti_spider/mflgGAGq.eot?') format('eot'); src: url('https://qidian.gtimg.com/qd_anti_spider/mflgGAGq.woff') format('woff'), url('https://qidian.gtimg.com/qd_anti_spider/mflgGAGq.ttf') format('truetype'); } .mflgGAGq { font-family: 'mflgGAGq' !important;     display: initial !important; color: inherit !important; vertical-align: initial !important; }</style><span class="mflgGAGq">&#100391;&#100389;&#100387;&#100394;&#100395;&#100394;&#100385;</span></span>收藏</p>

代码直接解析出来就是下面这个:

𘠧𘠥𘠣𘠪𘠫𘠪𘠡收藏

猜测&#100391;&#100389;&#100387;&#100394;&#100395;&#100394;&#100385;这一串字符以分号分隔,更好对应7位,解密之后会不会就是我们需要的收藏数?

5、字体解密

源码中返回的是编码后的数据。
解决方案:
将字体下载下来,转换成xml,然后分析源码数据和xml数据之间的对应关系。起点网中:源码的十进制,对应的是xml中map标签的code属性值的十六进制。

5.1 获取字体文件并解析为xml

字体文件一般是xxx.woff,并解析为xml文件,fontTools为第三方库,使用前请先安装pip install fontTools

# coding=utf-8
import requests
from fontTools.ttLib import TTFont
import time

headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}


def get_woff(url):
    response = requests.get(url, headers=headers)
    with open('font.woff', 'wb') as f:
        f.write(response.content)


def parseToXml(file):
    f = TTFont(file)
    f.saveXML('font.xml')


if __name__ == "__main__":
    url = "https://qidian.gtimg.com/qd_anti_spider/mflgGAGq.woff"  # url
    file = r"C:\Users\Administrator\PycharmProjects\Test\selenium_test\font.woff"
    get_woff(url)
    time.sleep(2)
    parseToXml(file)

woff文件对应路径是上面提到的这个路径:
在这里插入图片描述

5.2 十进制字符转化为十六进制

10进制字符&#100391;&#100389;&#100387;&#100394;&#100395;&#100394;&#100385;转化为16进制

data = "&#100391;&#100389;&#100387;&#100394;&#100395;&#100394;&#100385"
num_list = []
numbers = data.split(';')
for num in numbers:
    if num:
    # %x:十六进制的占位符
    res = '%x' % int(num.replace('&#', ''))
    num_list.append(res)
print(num_list)

10进制字符进行转化之后,得到这样一个7位十六进制数的列表
在这里插入图片描述

5.3 根据十六进制数据反查xml文件字典

[‘18827’, ‘18825’, ‘18823’, ‘1882a’, ‘1882b’, ‘1882a’, ‘18821’]
解析的xml文件中的部分内容如下:
在这里插入图片描述
我们可以看到18827对应name='six’也就是数字6,18825对应name=‘nine’也就是数字0…
所以列表[‘18827’, ‘18825’, ‘18823’, ‘1882a’, ‘1882b’, ‘1882a’, ‘18821’]对应的就是数字[6,0,5,8,1,8,2],拼接起来就是6958182,对应的就是这个收藏数据了
在这里插入图片描述

6、最后

完整的代码我就不贴了,这里只是展示一个字体解析的思路,加密必然对应一个密码本,密码本(xml)我们已经得到了,把加密的内容解密出来就相对容易了,至于怎么解析xml标签结构,请求网页源代码,提取出字体文件woff,这里我就不赘述了,感兴趣的小伙伴可以自己去研究下…喜欢的点个赞吧~!


http://www.niftyadmin.cn/n/898890.html

相关文章

Windows平台chrome webdriver的下载与安装

1、确认Chrome浏览器的版本 1.打开Chrome浏览器&#xff0c;点击右上角的三个点样式图标&#xff0c;然后先帮助&#xff0c;再点击关于 Google Chrome 2.得到当前的版本号&#xff0c;比如我的是91.0.4472.124 2、下载对应的Webdriver 1、下载地址http://npm.taobao.org/…

selenium+requests获取52PK英雄联盟各英雄皮肤

简介 目标站点&#xff1a;https://lol.52pk.com/pifu/hero 实现方式&#xff1a;selenium进行图片信息获取并翻页&#xff0c;requests请求图片的url并保存图片到本地 Python实现 运行程序前&#xff0c;请先确认已经安装了requests、selenium第三方模块&#xff0c;并下载了…

百度文字识别OCR识别图片文字内容

AI接入 参考官方文档&#xff1a;AI接入指南 参考&#xff1a;网络图片文字识别申请 参考&#xff1a;鉴权认证机制&#xff0c;用于获取access token 网络文字识别示例代码 下面是官方给的示例代码&#xff0c;从代码中我们可以看出&#xff0c;只要获取到access_token就…

pandas计算excel两列的日期差

原始Excel数据 诉求&#xff1a;往Excel中追加两列"当前时间"、“时间差”&#xff0c;计算日期和当前时间相差的天数、小时、秒&#xff0c; 注&#xff1a;一天等于86400秒 插入两列数据到表格 # codingutf-8 import pandas as pd import datetimedf pd.read_ex…

CentOS 7安装实时监控日志文件的swatchdog

swatchdog介绍 swatchdog是从一个用于监视Unix syslog工具生成的日志的脚本发展起来的&#xff0c;它可以监视任何类型的日志。swatchdog(Simple WATCH DOG)是一个简单的Perl脚本&#xff0c;用于监视类Unix系统(比如Linux)上的活动日志文件。它根据可以在配置文件中定义的正则…

虚拟机获取不到IP的解决办法

新创建的CentOS 7虚拟机&#xff0c;使用的DHCP获取地址&#xff0c;一直获取不到IP地址&#xff0c;service network restart命令执行多次都不行&#xff0c;使用如下方式后OK su - root dhclient -vifconfig

yum命令安装软件报错One of the configured repositories failed (未知)

报错 [rootlocalhost yum.repos.d]# yum install ansible 已加载插件&#xff1a;fastestmirrorOne of the configured repositories failed (未知),and yum doesnt have enough cached data to continue. At this point the onlysafe thing yum can do is fail. There are a …

-bash: zabbix_get: command not found解决办法

zabbix_get zabbix-get命令是server端用来检查agent端的一个命令&#xff0c;可以用zabbix_get来检查能否采集到数据&#xff0c;进行问题定位 安装 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm yum clean all yum insta…