操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    TL;DR

    本系列文章將介紹如何從epub格式文件中提取結(jié)構(gòu)化數(shù)據(jù),并存入在線數(shù)據(jù)庫(kù)(),進(jìn)而利用該數(shù)據(jù)庫(kù)自帶的接口生成能力,在無(wú)需后端編碼的情況下,完成自用電子圖書(shū)館的開(kāi)發(fā)。

    最終效果

    數(shù)據(jù)元數(shù)據(jù)信息提取

    明確epub本身是個(gè)壓縮文件書(shū)籍是壓縮包格式,解壓后包含了一些基本的文件結(jié)構(gòu),如下圖所示:

    格式工廠mp4格式怎么壓縮視頻_mpeg格式壓縮_書(shū)籍是壓縮包格式

    其中OEBPS

    文件夾下的.opf

    文件是標(biāo)準(zhǔn)的XML

    文件,該文件的

    標(biāo)簽下的內(nèi)容包含了許多書(shū)籍元數(shù)據(jù)信息,如下圖所示:

    "cover.jpg">書(shū)籍封面
    ??書(shū)名
    ?????制作人
    ?????????主題關(guān)鍵詞
    ?????????????描述
    ?????????????????出版商
    ?????????????????????貢獻(xiàn)者
    ?????????????????????????發(fā)布日期
    ?????????????????????????????type>類型
    ?????????????????????????????????格式
    ?????????????????????????????????????唯一標(biāo)識(shí)符
    ?????????????????????????????????????????source>來(lái)源
    ?????????????????????????????????????????????語(yǔ)言
    ?????????????????????????????????????????????????關(guān)聯(lián)
    ?????????????????????????????????????????????????????覆蓋范圍
    ?????????????????????????????????????????????????????????權(quán)責(zé)描述

    既然每本epub格式的電子書(shū)都包含書(shū)籍元數(shù)據(jù)信息,那就可以寫(xiě)個(gè)程序提取這些數(shù)據(jù)信息存入到數(shù)據(jù)庫(kù)中,后續(xù)寫(xiě)個(gè)接口來(lái)檢索就行。

    書(shū)籍是壓縮包格式_mpeg格式壓縮_格式工廠mp4格式怎么壓縮視頻

    那問(wèn)題來(lái)了:哪來(lái)的那么多epub格式電子書(shū)啊?

    寫(xiě)個(gè)爬蟲(chóng)去爬?額,法律風(fēng)險(xiǎn)太大,一不小心就讓你去局子里寫(xiě)《鐵窗淚》,不值當(dāng)。

    從網(wǎng)盤(pán)上下載人家分享的書(shū)籍壓縮包,然后寫(xiě)程序提取?我用的是阿里云盤(pán)(下載不限速),書(shū)籍壓縮包鏈接是從網(wǎng)上搜的。

    提取數(shù)據(jù)

    ????/**
    ?*?具體實(shí)現(xiàn)方式:
    ?*?構(gòu)建一個(gè)扁平化的source目錄,目錄中均為epub后綴的文件
    ?*?從source目錄下,找到一個(gè)epub文件,并將其mv到一個(gè)stage目錄
    ?*?在stage目錄中,以zip到方式解壓該epub,并搜索到content.opf文件
    ?*?然后利用xml2js,解析content.opf,如果能夠成功解析,并且能獲得title/cover這兩個(gè)關(guān)鍵信息,其中cover必須存在
    ?*?那么將圖片重命名為時(shí)間戳(為了避免時(shí)間戳泄露數(shù)據(jù)創(chuàng)建信息,統(tǒng)一減去固定值)
    ?*?將圖片成功移動(dòng)到covers目錄,并將原始的epub文件重命名后移入到books目錄,同時(shí)將提取到的元數(shù)據(jù)信息寫(xiě)入數(shù)據(jù)庫(kù),如果這三個(gè)條件都滿足,則進(jìn)行下一個(gè)循環(huán)
    ?*?如果上述三個(gè)條件不滿足,則回滾操作,將從covers目錄移除圖片,將epub文件從books目錄移動(dòng)到failed目錄
    ?*/

    const?SOURCE_DIR?=?path.resolve(__dirname,?'source');
    const?STAGE_DIR?=?path.resolve(__dirname,?'stage');
    const?COVERS_DIR?=?path.resolve(__dirname,?'covers');
    const?FAILED_DIR?=?path.resolve(__dirname,?'failed');
    const?BOOKS_DIR?=?path.resolve(__dirname,?'books');


    //?定義需要處理到文件名
    let?targetFile;

    //?讀取目錄下到文件名,并留存為列表
    let?files?=?fs.readdirSync(SOURCE_DIR);
    files?=?files.filter(item?=>?!(/(^|\/)\.[^\/\.]/g).test(item));?//?過(guò)濾隱藏文件

    let?i?=?0;
    //?遍歷source下到文件,開(kāi)始提取信息
    while?(i?
    ????await?shell.mv(path.join(SOURCE_DIR,?files[i]),?STAGE_DIR);
    ????console.log('mv?stage');

    ????targetFile?=?path.join(STAGE_DIR,?files[i]);

    ????//?step?2:?利用jszip讀取文件
    ????try?{
    ????????const?data?=?await?readFileAsync(targetFile);
    ????????const?zip?=?await?JSZip.loadAsync(data);

    ????????console.log('--------?start?extracting?----------')
    ????????const?metaFileIndex?=?Object.keys(zip.files).findIndex((item?=>?item.includes("content.opf")));
    ????????const?metaFileName?=?Object.keys(zip.files)[metaFileIndex];
    ????????let?coverLink?=?'';
    ????????let?cover?=?'';
    ????????const?content?=?await?zip.file(metaFileName).async('text');
    ????????let?id?=?'';
    ????????let?title?=?'';
    ????????let?author?=?'';
    ????????let?publisher?=?'';
    ????????let?link?=?'';
    ????????let?date?=?'';
    ????????let?language?=?'';

    ????????const?metaResult?=?await?xmlParserWithoutAttr.parseStringPromise(content)
    ????????const?metadata?=?metaResult.package.metadata[0];

    ????????id?=?uuid();
    ????????title?=?metadata['dc:title']???metadata['dc:title'][0]?:?'';
    ????????author?=?metadata['dc:author']???metadata['dc:author'][0]?:?'';
    ????????publisher?=?metadata['dc:publisher']???metadata['dc:publisher'][0]?:?'';
    ????????link?=?`${uuid()}.epub`;
    ????????date?=?metadata['dc:date']???metadata['dc:date'][0]?:?'';
    ????????language?=?metadata['dc:language']???metadata['dc:language'][0]?:?'';


    ????????const?maniResult?=?await?xmlParser.parseStringPromise(content);
    ????????const?maniMeta?=?maniResult.package.metadata[0];
    ????????const?manifest?=?maniResult.package.manifest[0].item;

    ????????let?coverId;
    ????????for?(let?i?=?0;?i?'meta'].length;?i++)?{
    ????????????const?child?=?maniMeta['meta'][i];
    ????????????if?(child.$.name?===?'cover')?{
    ????????????????console.log(child);
    ????????????????coverId?=?child.$.content;
    ????????????????break;
    ????????????}
    ????????}

    ????????for?(let?item?of?manifest)?{
    ????????????if?(item.$.id?===?coverId)?{
    ????????????????cover?=?item.$.href;
    ????????????????break;
    ????????????}
    ????????}

    ????????if?(cover)?{
    ????????????coverLink?=?uuid()?+?cover.substring(cover.lastIndexOf('.'));
    ????????????const?coverIndex?=?Object.keys(zip.files).findIndex((item?=>?item.includes(cover)));
    ????????????const?coverName?=?Object.keys(zip.files)[coverIndex];
    ????????????const?coverContent?=?await?zip.file(coverName).async('uint8array');
    ????????????await?writeFileAsync(path.join(COVERS_DIR,?coverLink),?coverContent);
    ????????}

    ????????//?TODO:?寫(xiě)入到數(shù)據(jù)庫(kù)

    ????????console.log(title,?'has?been?extract?data?successfully!');

    ????????await?shell.mv(targetFile,?`${BOOKS_DIR}/${link}`);
    ????}?catch?(e)?{
    ????????console.log(e);
    ????????await?shell.mv(targetFile,?FAILED_DIR);
    ????}

    ????i++;
    }?//?end?while

    格式工廠mp4格式怎么壓縮視頻_mpeg格式壓縮_書(shū)籍是壓縮包格式

    寫(xiě)入數(shù)據(jù)庫(kù)

    上述代碼已經(jīng)可以提取書(shū)籍元數(shù)據(jù), 而我我需要將每一次提取的數(shù)據(jù)元數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù),但我又不想在本地安裝一個(gè)數(shù)據(jù)庫(kù),更不想去學(xué)一個(gè)ORM來(lái)琢磨如何連接并訪問(wèn)數(shù)據(jù)庫(kù)。

    恰好我找到了

    這個(gè)免費(fèi)在線數(shù)據(jù)庫(kù)。它能基于我建的表,直接生成數(shù)據(jù)庫(kù)訪問(wèn)接口,而接口調(diào)用是直接使用它提供的SDK,簡(jiǎn)直不要太爽。

    step1

    直接微信掃碼登錄后(似乎掃碼就完成了注冊(cè)和登錄),創(chuàng)建一個(gè)應(yīng)用,取名叫ebook

    格式工廠mp4格式怎么壓縮視頻_書(shū)籍是壓縮包格式_mpeg格式壓縮

    應(yīng)用創(chuàng)建完,直接進(jìn)入應(yīng)用,根據(jù)我需要的數(shù)據(jù)結(jié)構(gòu)創(chuàng)建一張表

    step2

    切換到API頁(yè)面,按照要求安裝@/-js

    ,并復(fù)制初始化

    的代碼到之前的代碼中

    書(shū)籍是壓縮包格式_格式工廠mp4格式怎么壓縮視頻_mpeg格式壓縮

    替換上述代碼的// TODO: 寫(xiě)入到數(shù)據(jù)庫(kù)為下述代碼

    try?{
    ????const?{error}?=?await?client.from('book').insert([
    ????????{
    ????????????id,
    ????????????title,
    ????????????author,
    ????????????publisher,
    ????????????link,
    ????????????date,
    ????????????language,
    ????????????cover_link:?coverLink
    ????????}
    ????])
    ????if?(!error)?{
    ????????console.log(title,?'write?to?db?failed!');
    ????}?else?{
    ????????console.log(title,?'has?been?extract?data?successfully!');
    ????}
    }?catch?(e)?{
    ????console.log(title,?'write?to?db?failed!');
    }

    step3

    在倉(cāng)庫(kù)根目錄下執(zhí)行yarn run 即可從epub文件中提取元數(shù)據(jù)并最終寫(xiě)入剛才在線數(shù)據(jù)庫(kù)中:

    小結(jié)

    本文介紹了epub格式文件的組成部分,創(chuàng)建了一個(gè)可從XML中提取元數(shù)據(jù)并寫(xiě)入在線數(shù)據(jù)庫(kù)的代碼樣例,在不學(xué)習(xí)任何第三方ORM,也無(wú)需掌握SQL,甚至連本地?cái)?shù)據(jù)庫(kù)都不創(chuàng)建的情況下更簡(jiǎn)單的完成了數(shù)據(jù)提取與寫(xiě)入的工作。更神奇的是書(shū)籍是壓縮包格式,后續(xù)我會(huì)演示如何在無(wú)需開(kāi)發(fā)后端接口的情況下,完成數(shù)據(jù)檢索、分頁(yè)等功能。

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有