python批量小说txt文件转json文件

前言

       最近在做一个项目涉及小说文件的处理,项目要提供小说在线观看的功能。
       因为小说文件大概有10GB放在mysql不切实际,而且希望用redis做一些缓冲,故小说文件转为json格式更方便数据操作。
       由于资源网站获取来的小说文件为txt格式,故需要用python进行一些转换,下文为本人的处理方式

原文件

  • 文件名格式
    1

  • 小说内容格式
    2

  • 编码格式
    小说txt文件为UTF-8编码
    注:原txt文件不为UTF-8需转换工具:下载

目标文件

  • 小说汇总文件book.json
    1

  • 各小说内容文件

    • 文件名格式 bookID.json
    • 文件格式
      1
      2

python代码


import os,sys
import json,re

class fileScanner(object):

        def __init__(self,dir):
            self.dir = dir
            self.files = []
            self.size = 0;
        
        def scanFile(self):
            ##扫描所有txt文件
           filetype ='.txt'
           file = {
                'fileName':'',
                'filePath':''
           }
           
           for parent,dirnames,filenames in os.walk(self.dir):
                for filename in filenames:
                    file = {
                    'fileName':'',
                    'filePath':''
                    }
                    file['fileName'] = filename
                    file['filePath']= os.path.join(parent, filename) 
                    if file['filePath'].find(filetype)!=-1:
                        self.files.append(file)
                        print("扫描到: "+file['filePath'])
                        self.size+=1


class bookTojson(object):
        def __init__(self,files):
            self.files = files
            self.books = []
        
        def readBookDetail(self,n):
            detail = {
                'bookID':n,
                'bookName':'无',
                'autor':'无',
                'bookType':'无'
            }
            fileName = self.files[n]['fileName']
            fileName = fileName.replace('.txt','')  #文件名清理
            fileName= re.sub(r'【(.*)】', "", fileName) #文件名清理
            
            detail['bookName'] = fileName #初始赋值小说名,防止为空
            if re.search(r'《(.*)》',fileName):
                #print('书名:'+re.search(r'《(.*)》',fileName).group().strip('《》'))
                detail['bookName'] = re.search(r'《(.*)》',fileName).group().strip('《》')
                fileName= re.sub(r'《(.*)》', "", fileName)
                
            if re.search(r'\[(.*)\]',fileName):
                #print('类别:'+re.search(r'\[(.*)\]',fileName).group().strip('[]'))
                detail['bookType'] = re.search(r'\[(.*)\]',fileName).group().strip('[]')
                
            if len(fileName.split('作者:'))>1:
                #print('作者:'+fileName.split('作者:')[1])#文件名编码为GB2312
                detail['autor'] = fileName.split('作者:')[1]
            
            
            self.books.append(detail)
        
        #输出小说内容为json    
        def writeJson(self,book,bookID):
            jsonArr = json.dumps(book, ensure_ascii=False, sort_keys=False, indent=4, separators=(',', ': '))
            filePath ='D:\\BaiduNetdiskDownload\\books\\bookJson\\'+str(bookID)+'.json'
            with open(filePath, 'w+', encoding='utf-8') as f:
                f.writelines(jsonArr)
        #
        #处理小说输出章节及内容
        def readBookContent(self,n):
            
            book = {
                'bookID':n,
                'bookName':self.books[n]['bookName'],
                'autor':self.books[n]['autor'],
                'bookType':self.books[n]['bookType'],
                'chapters':[],##章节 item {}
                'contents':{}##
            }
            
            chapterName = ''
            content = ''
            
            fopen=open(self.files[n]['filePath'],encoding = 'utf-8',mode = 'r') 
            lines=[]
            lines=fopen.readlines()
            index = 1  #章节号
            flag = 0  #读取到章节内容的标志
            for line in lines:    
                if len(line)>0:
                    if re.match(r'^(\\s*)',line)==None:
                        if ord(line[0])!=12288:
                            #读取到章节标题
                            #print(line)
                            chapterName+=(line+' ')
                            flag = 0 
                        else:
                            #读取到章节内容
                            
                            if flag == 0:
                                flag =1
                                #可以写入章节内容
                            else:
                                flag+=1
                                content+=line
                    else:
                        #读取到章节内容
                        
                        if flag == 0:
                            flag =1
                            #可以写入章节内容
                        else:
                            flag+=1
                            content+=line
                                
                if flag == 1 :
                    #上一章内容写入
                    if index > 1:
                        book['contents'][str(n)+str(index-1)] = content
                        content = line #新章节内容开始
                    if chapterName != None:
                        chapter = {
                        'chapterID':'',
                        'chapterName':'无',
                        } #注意字典for内赋值问题
                        
                        chapter['chapterID'] = str(n)+str(index)
                        chapter['chapterName'] = chapterName
                        chapterName = ''
                        book['chapters'].append(chapter)
                        
                    #章节标题读取结束
                    index += 1
                    
            #末端章节
            book['contents'][str(n)+str(index-1)] = content
            self.writeJson(book,n)   
            #print(json.dumps(book, ensure_ascii=False, sort_keys=False, indent=4, separators=(',', ': ')))  
                    
        def runFun(self,n):
         try:
            self.readBookDetail(n)
            self.readBookContent(n)
         except Exception:
            print('文件'+str(n)+'错误')
            



if __name__ == "__main__":
    #填入小说文件夹名
    fs = fileScanner("D:\\BaiduNetdiskDownload\\books\\books") #注意路径带双斜杠 防止出现转义字符\n等
    print('获取小说文件名:')
    fs.scanFile()        
    bTj = bookTojson(fs.files)    
    print('开始处理小说:')
    for i in range(0,len(fs.files)):
        bTj.runFun(i)
        sys.stdout.write("  已处理:%.3f%%" %  float(((i/len(fs.files)))*100) + '\r')
        sys.stdout.flush()
    print('小说处理完成')
    
    
    data=bTj.books
    jsonArr = json.dumps(data, ensure_ascii=False, sort_keys=False, indent=4, separators=(',', ': '))
    print('文件json格式已输出')
    with open('books.json', 'w+', encoding='utf-8') as f:
        f.writelines(jsonArr)
       
    print("小说数%d"%fs.size)

运行结果

1
2

后言

然后10个G的2000部小说大概跑了一个小时才全部转为json ヽ(ー_ー)ノ ,算法问题欢迎大佬指正下方留言,注:需要资源也可下方留言

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值