吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4512|回复: 47
上一主题 下一主题
收起左侧

[其他原创] 如何将保存的微信文章连同评论优雅地转为电子书

  [复制链接]
跳转到指定楼层
楼主
侃遍天下无二人 发表于 2023-4-6 20:59 回帖奖励
本帖最后由 侃遍天下无二人 于 2023-4-6 21:12 编辑

这段时间因为各种需要和电子书相关的处理工具打交道比较多,恰好最近也更新了微信文章下载器,但下载器下下来的文章并不适合直接用pandoc转为电子书,因为里面有许多多余的层级结构,可能会导致排版出问题。我先前的做法是把需要制成电子书的文章复制粘贴到 typora 中,这样它就被规范成md格式了,然后再用pandoc将md转为epub。
但现在想来,这样搞存在大量需要手工处理的点,效率太低,于是这两天我基于这段时间积累的经验,稍微研究了一下要如何处理下载下来的微信文章,使之能被pandoc很好地从html直接转成epub格式,并尽量减少后续的处理步骤。研究成果与大家分享一下:

首先,我们不妨以吾爱破解的公众号为例(主要是放其他公众号有推广嫌疑),下载其中推送的 10 篇原创文章:

然后用pandoc将其中一篇直接转为epub,发现阅读体验非常差,甚至根本就读不到东西:


显然我们应该尽量简化写入html的样式结构,才能提升转换的质量。
我们打开调试工具,可以定位到一个恰好覆盖了整篇文章的节点,节点的id为 js_content

另外,对于已经保存到本地的留言,它总是被包裹在
[HTML] 纯文本查看 复制代码
<!--cmt_start-->
[HTML] 纯文本查看 复制代码
<!--cmt_end-->
之间,可以直接用正则表达式提取,此外,留言的样式也很简单,只有如下几条,可以将其写入一个css文件让pandoc使用:
[CSS] 纯文本查看 复制代码
.avatar{width:32px;height:32px;margin-right:12px;border-radius:3px;margin-top:4px}.nickname_wrp{margin-top:5px;margin-bottom:5px;color:rgba(0,0,0,.5)}.reply_result.js_reply_item{border-left:5px solid #aaa;padding-left:15px}


这样,就可以将文章重组成较为精简的样式,从而提升转换质量。




具体要如何转换呢?下面就以golang为例,进行说明:

首先,我们需要将html文件全部读入内存,并转为字符串形式方便后续处理(代码略)。

接下来,我们要对字符串进行解析,这样才能执行dom操作,解析会用到 "golang.org/x/net/html" 包,代码如下:
[Golang] 纯文本查看 复制代码
doc, _ := html.Parse(strings.NewReader(content))


解析的目的是便于取出文章节点,并将其子节点全部转为字符串,我们编写一个findElementById函数实现:
[Golang] 纯文本查看 复制代码
func findElementById(n *html.Node, id string) *html.Node {
        if n.Type == html.ElementNode && n.Attr != nil {
                for _, attr := range n.Attr {
                        if attr.Key == "id" && attr.Val == id {
                                return n
                        }
                }
        }
        for c := n.FirstChild; c != nil; c = c.NextSibling {
                if result := findElementById(c, id); result != nil {
                        return result
                }
        }
        return nil
}

虽然函数看上去有点啰嗦,但调用起来很简单:
[Golang] 纯文本查看 复制代码
imgContent := findElementById(doc, "js_content")


取得这个节点后,我们要将其子节点全部转为字符串,以便后续重新写入文件:
[Golang] 纯文本查看 复制代码
innerHtml := extractInnerHTML(imgContent)


函数实现如下:
[Golang] 纯文本查看 复制代码
// 提取节点的innerHTML
func extractInnerHTML(n *html.Node) string {
        var h string
        for c := n.FirstChild; c != nil; c = c.NextSibling {
                h += renderNode(c)
        }
        return h
}

// 将节点渲染为HTML字符串
func renderNode(n *html.Node) string {
        var h string
        switch n.Type {
        case html.ErrorNode:
                h = fmt.Sprintf("<!--%s-->", n.Data)
        case html.TextNode:
                h = n.Data
        case html.DocumentNode, html.ElementNode:
                h = fmt.Sprintf("<%s", n.Data)
                for _, a := range n.Attr {
                        h += fmt.Sprintf(` %s="%s"`, a.Key, a.Val)
                }
                if n.Type == html.ElementNode {
                        h += ">"
                }
                for c := n.FirstChild; c != nil; c = c.NextSibling {
                        h += renderNode(c)
                }
                if n.Type == html.ElementNode {
                        h += fmt.Sprintf("</%s>", n.Data)
                }
        case html.CommentNode:
                h = fmt.Sprintf("<!--%s-->", n.Data)
        }
        return h
}

当然,既然是innerHTML,取得的内容是不包含节点本身的,我们用字符串拼接给它补上:
[Golang] 纯文本查看 复制代码
innerHtml = "<div class=\"rich_media_content js_underline_content autoTypeSetting24psection\" id=\"js_content\" style=\"visibility: visible;\" deep=\"5\">" + innerHtml + "</div>"


文章标题也需要统一包上h2样式,方便pandoc处理,这个可以从文件名或者html的元数据中直接获取:
[Golang] 纯文本查看 复制代码
title = "<h2 class=\"rich_media_title \" id=\"activity-name\">" + title + "</h2>"


最后就是评论区的内容,这个直接用正则表达式找出来就好了
[Golang] 纯文本查看 复制代码
 var REG_CMT = regexp.MustCompile("(?s)<!--cmt_start-->.*<!--cmt_end-->")


做完这些,我们就可以直接把处理结果返回了
[Golang] 纯文本查看 复制代码
submatch := REG_CMT.FindAllStringSubmatch(content, 1)
        if len(submatch) == 1 {
                return title + innerHtml + submatch[0][0]
        } else {
                return title + innerHtml
        }
[/mw_shl_code]

如下图,这就是处理后的html直接转为epub的效果,虽然浏览器上的阅读体验变差了,但转格式后的阅读体验有所提升:


当有多篇文章同时存在时,可以先将这些文章用二进制合并拼接成一个文件,再用pandoc转格式,最后用calibre编辑一下,并根据标题重新生成目录,就能得到一本效果还算不错的电子书了

转换并简单处理后的成品已上传,可以看看效果,祝大家玩得开心!
顺便说一下,这个功能后续会加入下载器中,期待的话请多多为我投票吧~


52pojie.epub - 蓝奏云
https://wwpv.lanzoue.com/iGIjw0s9nn5e

免费评分

参与人数 9吾爱币 +17 热心值 +9 收起 理由
q7634356 + 1 + 1 我很赞同!
三滑稽甲苯 + 2 + 1 本来挺喜欢下载器的
daofawubian + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
话痨司机啊 + 2 + 1 我很赞同!
Meton + 1 + 1 我很赞同!
wushaominkk + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
慕云轻 + 1 + 1 我很赞同!
xhclso + 1 + 1 谢谢@Thanks!
blindcat + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
落曌乾坤 发表于 2023-10-19 17:25
本帖最后由 落曌乾坤 于 2023-10-19 18:01 编辑
侃遍天下无二人 发表于 2023-10-19 13:55
你确定这个不是开了暗黑模式吗,用手机打开网页试试,我也装个最新的Chrome验证下

可能是。
Edge和Firefox设置成默认或自动,背景都是黑色,只有设置成light才行,Chrome没找到设置的地方,把Auto Dark Mode for Web Contents设置成disable是不行的。

只有微信公众号的文章用chrome打开会出现这种情况,论坛界面不会,还是白色背景的。

Edge.jpg (14.32 KB, 下载次数: 0)

Edge

Edge

Firefox.jpg (18.45 KB, 下载次数: 0)

Firefox

Firefox

点评

因为论坛没有暗黑模式啊 [attachimg]2650445[/attachimg]  详情 回复 发表于 2023-10-20 15:10
推荐
 楼主| 侃遍天下无二人 发表于 2023-10-17 09:50 |楼主
qytang 发表于 2023-10-16 14:48
下载下来的html用wkhtmltopdf转换成的pdf内容是空的,大佬有好的解决办法么

不考虑性能问题的话,建议整合为一个文件后直接用浏览器打印,微信文章的样式太复杂了,别的软件可能都处理不好
或者就是按照电子书格式下下来再转格式试试
沙发
wyl7956851 发表于 2023-4-6 21:04
3#
tom350 发表于 2023-4-6 21:18
感谢分享,学到了
4#
coverme 发表于 2023-4-6 21:25
感谢研究,这信息孤岛,敏感和谐
5#
Lingem 发表于 2023-4-6 21:30
深度好文
6#
lqwlzc 发表于 2023-4-6 21:37
解决了燃眉之急
7#
tingxiazrl 发表于 2023-4-6 21:39
感谢分享!先去试试
8#
Eixxon 发表于 2023-4-6 21:44
很有用有空试试谢谢
9#
cpteling 发表于 2023-4-6 21:57
版主威武
10#
adamfh 发表于 2023-4-6 22:01
正需要,感谢分享。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-29 14:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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