最近沉迷于将各种博客和官方文档html转化成pdf,结果用手机看还是不太方便,所以想到将html转化成epub格式的电子书,要用os,re,requests,lxm,zipfile,五个库,在这里分享下大概思路。我们的目标是太白金星博客园的python基础教程--太白教你学python,目录url:https://www.cnblogs.com/jin-xin/p/9076242.html。 第一步,利用requests库访问第一个目录url,用re或者lxml中的etree,获取目录中对应章节的url和标题。urls,names两个列表。示例代码如下: import requests from lxml import etree import os import re from fake_useragent import UserAgent headers = {'User-Agent': UserAgent().random} r = requests.get(url=url, headers=headers) r.encoding = r.apparent_encoding html = etree.HTML(r.text) lis = html.xpath('.//a[@target='_blank']')[1:] urls = [i.xpath('@href')[0] for i in lis] names = [i.text for i in lis] 第二步,for循环urls列表,利用requests库访问对应章节的url来,并用re对其进行处理,来获取我们需要放进epub的数据内容。(这里解释下为什么要用re不用etree,etree一般是用来获取格式化的标签的属性值,而re则是从html源代码上直接获取片段内容,在这里我们需要的就是网页源代码。)我们需要的是文本内容问html和示例图片img这两种数据,至于多余网页导航,侧边栏,评论,广告之类的通通不要。在这里发现获取到的图片标签的src都是网络url,而epub中只能从本地路径中导入,因此获取img标签的src属性值,将图片下载到本地文件夹中按数字编号保存文件名(1.png,2.png,3.png....),并用re.sub将文本html中的img的src属性替换成本地路径,将html写入本地文件前我们需要将其包裹在 标签中,并增加标签构成一个完整的网页,有需要还可以增加title标签。到这里,我们需要的数据就准备好了。示例代码如下:nums = len(names) num = 0 os.chdir('D:\藏书馆\小说') img_num = 1 while num < nums: r = requests.get(url=urls[num], headers=headers) r.encoding = r.apparent_encoding html = r.text html = re.findall('( ',html,flags=re.S)[0]imgs = re.findall('< img src='(.+?)' alt=''>',html) print(len(imgs)) for i in imgs: try: r = requests.get(url=i, headers=headers) with open(f'{img_num}.png', 'wb')as f: f.write(r.content) html = re.sub('< img src='(.+?)' alt=''>',f'< img src='../Images/{img_num}.png'>',html,1) img_num += 1 except: print(i) name = names[num] for tsstr in ':!~?:'.。,、?;:!·~()[]{}()【】{}': name = name.replace(tsstr, '') name=f'{num:<3}'+ ' ' + name with open(f'{name}.html','w', encoding='utf-8')as f: f.write(html) num+=1 print(f'{name}下载完毕,当前下载进度:{num}/{nums}') 第三步,创建一个文件夹,把它压缩后就是我们的.epub文件了,当然不是现在就压缩啦!文件夹目录如下: 一级目录中有两个文件夹和一个文件,META-INF文件夹,OEBPS文件夹和mimetype文件。mimetype文件里面只写一行:application/epub+zip,NETA-INF文件夹中只有一个container.xml文件,内容是: <?xml version='1.0' encoding='utf-8'?> OEBPS文件夹中有Images文件夹,Text文件夹,和content.opf文件与toc.ncx文件。 Images文件夹中存放所有的img图片,Text文件夹中存放所有的html文件,content.opf文件是Images与Text中所有文件的一个清单,格式如下: <?xml version='1.0' encoding='utf-8'?> urn:uuid:758b33c6-6ddb-4d52-a91c-50b137b50ef3 en [此处填写标题] 2020-11-04 ...... ...... toc.ncx文件是目录文件,格式如下: <?xml version='1.0' encoding='UTF-8'?> /p> [此处填写标题] 一,Python介绍 1. python的出生与应用 2. python是什么编程语言。 3. python的优缺点。 4. python的种类。 二. python环境 ...... 这两个文件都可以利用os库一键生成,至此所有文件数据准备完毕。 第四步,利用zipfile库,和os库压缩文件合成.epub文件。一定要把mimetype文件第一个写入,再将其他固定文件(r'META-INF\container.xml',r'OEBPS\content.opf',r'OEBPS\toc.ncx')写入,最后将.html和.png文件逐个写入,示例代码如下: import zipfile import os os.chdir(r'C:\Users\My\Desktop\新建文件夹') epub = zipfile.ZipFile(r'C:\Users\My\Desktop\新建文件夹.epub','w') epub.write('mimetype',compress_type=zipfile.ZIP_STORED) print(os.listdir('.')) for i in [r'META-INF\container.xml',r'OEBPS\content.opf',r'OEBPS\toc.ncx']: epub.write(i, compress_type=zipfile.ZIP_DEFLATED) for p in [r'.\OEBPS\Images', r'.\OEBPS\Text']: for f in os.listdir(p): print(os.path.join(p,f)) epub.write(os.path.join(p,f),compress_type=zipfile.ZIP_DEFLATED) epub.close 至此,我们的epub格式电子书就制作完成了,以上内容只是我个人的想法和做法,欢迎大家一起加入讨论,另附:今天,你变得更博学了吗? |
|