IOS看书最终选择|源阅读转换|开源阅读|IOS自签

news2024/9/24 5:25:42

环境:IOS想使用 换源阅读
问题:换新手机,源阅读下架后,没有好的APP阅读小说
解决办法:自签APP + 转换源仓库书源

最终预览 :https://rc.real9.cn/

背景:自从我换了新iPhone手机,就无法使换源阅读了,于是我自用上,结果发现现在的书源发展的很快,旧版本的源阅读APP部分书源的语法不支持,于是我反复总结对比,写了一个自动转换的python程序,如上链接

解决过程:自签APP+转换书源

文章目录

    • 1.下载 ipa:
    • 2.自签IPA:
    • 3.转换书源
      • 3.1 获得书源
      • 3.2 转换规则
      • 3.3 转换书源
    • 4.在线转换
      • 4.1 web版源代码:
      • 4.2 我还写了个docker版本的


1.下载 ipa:

下载地址我就不放了

2.自签IPA:

关于怎么自签,你们可以用轻松签、全能签,小白啥也不会就算了

3.转换书源

3.1 获得书源

源仓库也不提供了,自己搜:
https://yuedu.miaogongzi.net/

3.2 转换规则

由于这款APP版本是2021年左右的,很多新版书源不支持,我们要进行转换,我自己花了点时间总结了一点转换规则:

最常见的规则是不支持a.1@text 这种,要转换,其他参考下列

书源类型
0    文本
2    视频
3    漫画
1    音频
-------------------------------
#    选择ID
.     选择元素 class之类
>     子元素
~     第二个,兄弟元素,同级关系
p:nth-child(2) 父元素的第n个子元素
[]    属性选择器            [class^=book] 选择class以book开头的元素
!    倒序选择器            img:!-1 选择最后一个img元素
||      列组合选择器            col||td 选择col和td元素
 ( )    分组选择器            (div,p) 选择所有div和p
,      多个选择器            .item, .active 选择item和active类
*       通用元素选择器        *.item 选择所有类名包含item的元素
n      表达式选择器            li:nth-child(3n) 按序选择li元素,每个li元素的父元素中的第 3、6、9、12等序号
a.-1@text     改为a:nth-last-child(1)@text
a.1@text         a:nth-child(1)@text```

### 3.3 步骤3.3

3.3 转换书源

现在开始转换,笨的办法是用记事本替换,我写了个python脚本来自动替换

import json
import requests

def replace_selectors(json_data):
    # 替换选择器的函数
    def replace_selector(selector):
        if "." in selector and "@" in selector:
            parts = selector.split('.')
            tag = parts[0]
            selector_part = parts[1]
            if "@" in selector_part:
                num, at_text = selector_part.split('@', 1)
                if ":" in num:
                    num, tag_after_colon = num.split(':', 1)
                    num = f"{num}@{tag_after_colon}"
                if num.replace("-", "").replace(".", "").isdigit():
                    num = "1" if num == "0" else num  # 处理小数点后面是0的情况
                    if num.startswith("-"):
                        num = num[1:]
                        return f"{tag}:nth-last-child({num})@{at_text}"
                    else:
                        return f"{tag}:nth-child({num})@{at_text}"
        return selector

    # 处理列表类型的 JSON 数据
    if isinstance(json_data, list):
        for item in json_data:
            replace_selectors(item)
        return

    # 遍历字典类型的 JSON 数据,查找并替换选择器
    for key, value in json_data.items():
        if isinstance(value, str):
            if "@" in value:
                value = replace_selector(value)
            json_data[key] = value
        elif isinstance(value, dict):
            replace_selectors(value)
        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    replace_selectors(item)

    # 增加替换规则,当"ruleExplore": []时,替换为"ruleExplore": "##"
    if "ruleExplore" in json_data and not json_data["ruleExplore"]:
        json_data["ruleExplore"] = "##"

if __name__ == "__main__":
    # 用户输入 JSON 文件的 URL
    json_url = input("请输入 JSON 文件的 URL: ")

    # 下载 JSON 数据
    response = requests.get(json_url)
    json_data = response.json()

    # 替换选择器
    replace_selectors(json_data)

    # 提取文件名,并保存 JSON 内容到文件
    file_name = json_url.split('/')[-1]
    with open(file_name, 'w', encoding='utf-8') as file:
        json.dump(json_data, file, indent=4, ensure_ascii=False)

    print(f"JSON 内容已按照新的替换原则进行替换并保存为文件:{file_name}")

4.在线转换

本地转换有点麻烦,我玩手机的时候电脑又不会一直在身边,我就把上面的代码改成了web版本,这些复制转换后的连接,到APP剪贴板导入就好了,效果如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.1 web版源代码:

import json
import os
import requests
from flask import Flask, render_template, request, send_from_directory, url_for
from werkzeug.utils import secure_filename

app = Flask(__name__)

def replace_selectors(json_data):
    # 替换选择器的函数
    def replace_selector(selector):
        if "." in selector and "@" in selector:
            parts = selector.split('.')
            tag = parts[0]
            selector_part = parts[1]
            if "@" in selector_part:
                num, at_text = selector_part.split('@', 1)
                if ":" in num:
                    num, tag_after_colon = num.split(':', 1)
                    num = f"{num}@{tag_after_colon}"
                if num.replace("-", "").replace(".", "").isdigit():
                    num = "1" if num == "0" else num  # 处理小数点后面是0的情况
                    if num.startswith("-"):
                        num = num[1:]
                        return f"{tag}:nth-last-child({num})@{at_text}"
                    else:
                        return f"{tag}:nth-child({num})@{at_text}"
        return selector

    # 处理列表类型的 JSON 数据
    if isinstance(json_data, list):
        for item in json_data:
            replace_selectors(item)
        return

    # 遍历字典类型的 JSON 数据,查找并替换选择器
    for key, value in json_data.items():
        if isinstance(value, str):
            if "@" in value:
                value = replace_selector(value)
            json_data[key] = value
        elif isinstance(value, dict):
            replace_selectors(value)
        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    replace_selectors(item)
    
    # 增加替换规则,当"ruleExplore": []时,替换为"ruleExplore": "##"
    if "ruleExplore" in json_data and not json_data["ruleExplore"]:
        json_data["ruleExplore"] = "##"

if __name__ == "__main__":
    @app.route('/', methods=['GET', 'POST'])
    def index():
        if request.method == 'POST':
            json_url = request.form['json_url']
            response = requests.get(json_url)
            json_data = response.json()
            replace_selectors(json_data)

            # 提取文件名,并保存 JSON 内容到文件
            file_name = json_url.split('/')[-1]
            json_dir = os.path.join(os.path.dirname(__file__), 'json')
            if not os.path.exists(json_dir):
                os.makedirs(json_dir)

            json_path = os.path.join(json_dir, file_name)
            with open(json_path, 'w', encoding='utf-8') as file:
                json.dump(json_data, file, indent=4, ensure_ascii=False)

            # 生成下载链接
            download_link = url_for('download', file_name=file_name)

            return render_template('result.html', json_data=json_data, download_link=download_link)
        return render_template('form.html')

    @app.route('/json/<path:file_name>', methods=['GET'])
    def download(file_name):
        json_dir = os.path.join(os.path.dirname(__file__), 'json')
        file_path = os.path.join(json_dir, file_name)
        return send_from_directory(json_dir, file_name, as_attachment=True)


    app.run(host='0.0.0.0', port=5000, debug=True)

4.2 我还写了个docker版本的

docker pull realwang/booksource_transios:latest
docker run -d  --name transios -p 5000:5000 booksource_transios

# 使用python3环境作为基础镜像
FROM python:3

# 设置工作目录
WORKDIR /app

# 安装git,用于从GitHub下载代码
#RUN apt-get update && apt-get install -y git

# 从GitHub下载代码
RUN git clone https://ghproxy.com/https://github.com/wangrui1573/booksource_transIOS.git /app

# 切换到代码目录
WORKDIR /app

# 安装python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 将容器5000端口映射到主机的5000端口
EXPOSE 5000

# 启动Python应用程序
CMD ["python", "api/conv_book_web.py"]


# docker run -d -p 5000:5000 booksource_transios

源代码:https://github.com/wangrui1573/booksource_transIOS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/823172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 搭建组件化私有库

一、创建私有库索引 步骤1是在没有索引库的情况下或者是新增索引的时候才需要用到&#xff08;创建基础组件库&#xff09; 首先在码云上建立一个私有库索引&#xff0c;起名为SYComponentSpec 二、本地添加私有库索引 添加私有库索引 pod repo add SYComponentSpec https:/…

fiddler 手机抓包(含https) 完整流程

第一部分&#xff1a;下载并安装fiddler 一.使用任一浏览器搜索【fiddler下载安装】&#xff0c;并下载fiddler 安装包。 二.fiddler安装包下载成功后&#xff0c;将下载的fiddler压缩包解压到自定义文件夹【fiddler】或者解压到当前文件夹下&#xff0c;双击文件夹中的【fidd…

工作记录------单元测试(持续更新)

工作记录------单元测试 之前的工作中从来没有写过单元测试&#xff0c;新入职公司要求写单元测试&#xff0c; 个人觉得&#xff0c;作为程序员单元测试还是必须会写的 于此记录一下首次编写单元测试的过程。 首先引入单元测试相关的依赖 <dependency><groupId>…

二、数据结构7:KMP 模板题+算法模板(KMP字符串)

文章目录 算法模板KMP题目模板 模板题KMP字符串原题链接题目思路题解 算法模板 KMP题目模板 // s[]是长文本&#xff0c;p[]是模式串&#xff0c;n是s的长度&#xff0c;m是p的长度 求模式串的Next数组&#xff1a; for (int i 2, j 0; i < m; i ) {while (j &&…

Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)

目录 一、启动zookeeper集群及kafka集群服务启动1.1、先启动三台zookeeper集群服务&#xff0c;再启动三台kafka集群服务1.2、使用PrettyZoo连接zookeeper客户端工具 二、在zookeeper服务端存储的Kafka相关信息 一、启动zookeeper集群及kafka集群服务启动 1.1、先启动三台zook…

一篇文章带你彻底搞懂方法重写(override)和重载(overload)—菜鸟教程学习记录

一篇文章带你彻底搞懂方法重写(override)和重载(overload) ​ 这个其实我们在之前的java方法那一章节里面就提到了&#xff0c;这里更加深入一下&#xff0c;并且提供具体的例子。 重写(Override)基本概念&#xff1a; ​ Java方法**重写(Override)**指的是&#xff0c;子类…

02 笔记本电脑m.2硬盘更换

1 工具展示 SN570的2T硬盘。够用了。 对于这台华为&#xff0c;使用的螺丝刀批头是4或5毫米的六边形批头。如果出现打滑的情况&#xff0c;请不要用蛮力哦。 2 更换过程 使用螺丝刀拧走后盖的螺丝&#xff08;为了避免会出问题要再次打开&#xff0c;我到现在还没有把螺丝拧回…

groovy.lang.GroovyRuntimeException:Ambiguous method

目录 问题 根因及解决 问题 今天线上的计算脚本报了个问题&#xff0c;报警如下是 groovy 运行时异常。调用方法 org.springframework.util.CollectionUtils#isEmpty 出现了异常。异常原因是由于方法重载造成了歧义。无法确定如何调用方法 [null]&#xff0c;因为它同时匹配了…

如何隐藏开源流媒体EasyPlayer.js视频H.265播放器的实时录像按钮?

目前我们TSINGSEE青犀视频所有的视频监控平台&#xff0c;集成的都是EasyPlayer.js版播放器&#xff0c;它属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;包括WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#x…

Stable diffusion 三大基础脚本 提示词矩阵,载入提示词,XYZ图表讲解

目录 0.本章讲解 1.提示词矩阵(prompt matrix) 1.2.提示词矩阵功能选项 1.2.1.把可变部分放在提示词文本的开头 1.2.2.为每张图片使用不同随机种子 1.2.3.选择提示词 1.2.4.选择分割符 1.2.5.宫格图边框&#xff08;像素&#xff09; 2.从文本框或文件载入提示词(Pro…

0基础学习VR全景平台篇 第75篇:多现场

多现场是指将多台设备的直播画面整合到一个直播活动链接里面&#xff0c;让用户自行选择切换要看哪个直播画面的功能。既可以是同一个活动的不同角度直播&#xff0c;也可以是异地的直播。多现场不需要导播台&#xff0c;并且可以同时支持平面直播和VR直播的混合切换。多现场仅…

excel中使地址按十六进制进行数值递增的函数

这里是尼德兰的喵工具相关文章&#xff0c;欢迎您的访问&#xff01; 如果文章对您有所帮助&#xff0c;期待您的点赞收藏&#xff01; 让我们一起为成为芯片前端全栈工程师而努力&#xff01; 在进行寄存器编写时很多时候会涉及到算地址的问题&#xff0c;通常32bit位宽的寄存…

Gin框架使用

Gin Gin框架安装与使用 下载安装Gin&#xff1a; go get -u github.com/gin-gonic/gin使用示例&#xff1a; package mainimport "github.com/gin-gonic/gin"func main() {//创建一个默认的路由引擎r : gin.Default()//GET:请求方式&#xff0c;/hello:请求路径/…

Vivado进行自定义IP封装

一. 简介 本篇文章将介绍如何使用Vivado来对上篇文章(FPGA驱动SPI屏幕)中的代码进行一个IP封装&#xff0c;Vivado自带的IP核应该都使用过&#xff0c;非常方便。 这里将其封装成IP核的目的主要是为了后续项目的调用&#xff0c;否则当我新建一个项目的时候&#xff0c;我需要将…

实现 rollup 实现多模块打包

rollup 是一个 JavaScript 模块打包器&#xff0c;可以将许多 JavaScript 库和应用程序打包成少量的捆绑包&#xff0c;从而提高了应用程序的性能。本文详细描述如何通过 rollup 实现多模块打包。 前提 项目的目录结构 先看下项目的 package.json 文件夹&#xff1a; {&qu…

LLaMA系列 | LLaMA和LLaMA-2精简总结

文章目录 1、LLaMA1.1、模型结构1.2、训练方式1.3、结论 2、LLaMA-22.1、相比LLaMA1的升级2.3、模型结构2.3.1、MHA, MQA, GQA区别与联系 2.4、训练方式 1、LLaMA &#x1f525; 纯基座语言模型 《LLaMA: Open and Efficient Foundation Language Models》&#xff1a;https:/…

CS5801国产HDMI转DP/edp(4k60)转换器方案芯片 可替代LT6711

CS5801是HDMI2.0b到DP1.4a转换器方案IC。CS5801 有一个HDMI2.0b .输入&#xff0c;带宽高达18Gbps.它支持辨别率是4k60Hz。对于DP1.4输出&#xff0c;由4条数据通道组成&#xff0c;支持1.62Gbps、 2.7Gbps、 5.4Gbps链路速率。内置可选SSC功能可降低EMI影响。嵌入式MCU基于32位…

3d虚拟vr汽车实景展厅吸引更多潜在消费者

随着人们对生活品质的追求&#xff0c;越来越多的消费者开始关注汽车的外观设计、内饰配置等方面。传统的展示方式已经不能满足消费者的需求&#xff0c;车辆VR虚拟漫游展示应运而生。借助VR虚拟现实和web3d开发建模技术&#xff0c;对汽车的外观、造型及信息数据进行数字化处理…

乳腺癌CT影像数据的深度学习:R语言与ANN神经网络构建高性能分类诊断模型

一、引言 乳腺癌是全球最常见的女性恶性肿瘤之一&#xff0c;也影响着男性的健康。据统计&#xff0c;每年有数百万人被诊断出患有乳腺癌[1]。乳腺癌的早期检测和准确诊断对于治疗和预后至关重要。然而&#xff0c;乳腺癌的早期诊断面临许多挑战&#xff0c;如图像解读的主观性…

第一堂棒球课:MLB全明星发展历程·棒球1号位

MLB全明星发展历程 1. MLB全明星的起源 MLB全明星是什么&#xff1f; MLB全明星&#xff0c;也就是MLB All-Stars&#xff0c;是指美国职业棒球大联盟&#xff08;Major League Baseball, MLB&#xff09;在每年举办的全明星赛。这项赛事汇集了全联盟各队的顶级球员&#xff…