どのようにPDF形式でホームページを保存しますか?

2778 ワード

学習目標:
PDF形式でウェブページを保存します.
学習内容:
  • nodejs web変換pdfライブラリ
  • nodejsサイクル
  • nodejsマルチスレッド制御
  • nodejsファイルと文字列処理
  • 背景
    最近突発的な奇想が起きて、ウェブサイトをpdf資料に転化したいです.携帯しやすくて、調べます.以下は学習過程を記録します.
    nodejs web変換pdfライブラリ
    まず、調査しました.このようなnodejsの利用可能なウェブ変換pdfのライブラリが見つかりました.pppeteer、中国語の文書は多くなく、npm initnpm install puppeteer、そしてREADMEを参照します.
    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto('https://exsample.com', {waitUntil: 'networkidle2'});
      await page.pdf({path: 'hn.pdf', format: 'A4'});
    
      await browser.close();
    })();
    
    nodejsサイクル
    次の第二ステップ、私は多くのページをダウンロードしたいですが、どうすればいいですか?ループ
    const puppeteer = require('puppeteer');
    
    async function downloadedPage(url){
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto(url, {waitUntil: 'networkidle2'});
      await page.pdf({path: url+'.pdf', format: 'A4'});
    
      await browser.close();
    });
    
    urls = ['example.com','another.com'];
    
    function main() {
    	urls.forEach(async function(url) {
            console.log(url);
            await downloadedPage(url);
            return;
        });
    }
    
    nodejsマルチスレッド制御
    効率を考慮すると、多くのページで一つずつダウンロードする効率が線形であることを考慮します.幸い、私たちのdownloadedPage関数自体は非同期です.しかし、これによってもたらされる問題は私たちのメモリが限られています.一旦urlsという配列が大きすぎます.メモリがあふれました.そのため:count down lockの考え方を採用して合併を制御します.同時ダウンロード数は10.
    async.mapLimit(urls, 10, async function(url) {
            console.log('todo downloads:',total);
            await downloadedPage(url);
            total--;
            return;
        }, function (err, result) {
            //        ,        
            //console.log(result);
        });
    
    nodejsファイルと文字列処理
    引き続き改善し、問題を解決し、プロジェクトの体験が予想通りになるようにします.私たちは他に何か予想がありますか?
  • ずっとパソコンをつけていたくないです.そのため、私たちはプログラムを検査します.downloadedPageに検出フラグメントを挿入すると、以下のようになる.
  •     filename = repalceAll('
    ','',filename); if(fs.existsSync(filename+'.pdf')) { console.log('skip'); return; }
    このように私はパソコンをつけてダウンロードできます.そしてシャットダウンして、翌日またダウンロードする時、すでに存在しているホームページを見たらスキップします.
  • 大きな行列を維持したくないです.ファイルを読み、ファイルリストを維持し、urlを列別に対応リストに入れてダウンロードすればいいです.
  • var paths = ['file1','file2'];  
    
        for (var i = 0; i < paths.length; i++) {
            var data = fs.readFileSync(paths[i]);
           //console.log(data.toString());
           //a.push.apply(a,b);
           urls.push.apply(urls,data.toString().trim().split(","));
        }
    
    学習の成果:
    https://github.com/SamYuan1990/SaveWeb2Pdf