「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」の動かないサンプルコード③

「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」の動かないサンプルコード③:


「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」の動かないサンプルコード③

「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」を購入し、ただいま勉強中です。

これね↓
Puppeteer入門 スクレイピング+Web操作自動処理プログラミング


68747470733a2f2f77732d66652e616d617a6f6e


動かないサンプルコードがいくつかありますね。

のちのち使えそうなコードはせっかくなので修正して残しておこうと思いました。


まずpuppeteerについて

「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」の動かないサンプルコード① の「まずpuppeteerについて」の項目をご覧ください。


7章の6,「ブログの画像を保存する」
これも「Puppeteer入門ースクレイピング+Web操作自動処理プログラミング」の動かないサンプルコード②と同じです。do { 処理 } while(true)の中にawait Promise.all([ 処理 ]);があって、その中にpage.clickがある。そのせいか?ループ途中でハングアップします。

解決方法も同じ。

const nextに、セレクタオブジェクト'a[rel="next"]'を代入するのではなく、そのhref属性(リンク先URL)を代入。'a[rel="next"]').href。

そしてPromise.allの中で、page.click()ではなくpage.goto()を使う。です。

したがって修正箇所はほんの2箇所です。

/// 修正日(2019年2月11日)修正箇所は'///--修正--///'の行です 
 
const puppeteer = require('puppeteer'); 
const path = require('path'); 
const request = require('request'); 
const { promisify } = require('util'); 
const fs = require('fs'); 
const delay = require('delay'); 
 
/** 
 * ファイルのダウンロードを行う. 
 * @param {string} url - ダウンロードするファイルのURL 
 */ 
const downloadFile = async (url) => { 
  // ダウンロードファイル名の確定. 
  const filename = url.split('/').pop(); 
  // ファイルの取得. 
  const res = await promisify(request)({ method: 'GET', uri: url, encoding: null }); 
  // 成功(200)したかどうか? 
  if (res.statusCode === 200) { 
    // 成功していればjsと同じフォルダーにファイル出力 
    await promisify(fs.writeFile)(path.join(__dirname, filename), res.body, 'binary'); 
  } else { 
    // 失敗した場合はエラー処理. 
    throw new Error(`${res.statusCode} ダウンロードエラー`); 
  } 
}; 
 
/** 
 * メインロジック. 
 */ 
(async () => { 
  // Puppeteerの起動. 
  const browser = await puppeteer.launch({ 
    headless: false, // Headlessモードで起動するかどうか. 
    slowMo: 50, // 指定のミリ秒スローモーションで実行する. 
  }); 
 
  // 新しい空のページを開く. 
  const page = await browser.newPage(); 
 
  // view portの設定. 
  await page.setViewport({ 
    width: 1200, 
    height: 800, 
  }); 
 
  // ページの遷移. 
  console.log('----------------------------------------goto'); 
  await page.goto('http://ryoichi0102.hatenablog.com/'); 
 
await delay(1000); // スクレイピングする際にはアクセス間隔を1秒あける. 
 
  // 先頭の記事のurlを取得し、そのurlへ遷移. 
  console.log('----------------------------------------goto'); 
  const firstPage = await page.evaluate(() => document.querySelector('#main article:nth-child(1) h1.entry-title a').href); 
  // const firstPage = 'http://ryoichi0102.hatenablog.com/entry/2018/12/28/101519'; 
  await page.goto(firstPage); 
 
await delay(1000); // スクレイピングする際にはアクセス間隔を1秒あける. 
 
  // 各記事に対してのそれぞれの処理. 
  do { 
    console.log('----------------------------------------do'); 
 
    const imageUrls = await page.evaluate(() => Array.from(document.querySelectorAll('img.hatena-fotolife')).map(img => img.src)); 
    for (url of imageUrls) { 
      console.log(`Downloading... ${url}`); 
      await downloadFile(url); 
    } 
 
    console.log('----------------------------------------eval next'); 
    // 最後の記事までたどると次へボタンは表示されないので、その場合はループを抜ける. 
    ///---修正---/// const next = await page.evaluate(() => document.querySelector('a[rel="next"]')); 
    const next = await page.evaluate(() => document.querySelector('a[rel="next"]').href); 
    console.log('--------------------------------------nextのhrefは、' + next);   
 
    if (next === null) { 
      break; 
    } 
 
    // process.on('unhandledRejection', console.dir); // Promise内の捕捉されなかった例外について表示する 
 
    // 次のページを読み込む. 
    console.log('----------------------------------------next'); 
 
    await Promise.all([ 
        console.log('----------------------------------------inside Promise.all'),   
        page.waitForNavigation({ waitUntil: 'load' }), 
        //page.goto('a[rel="next"]'), 
        page.goto(next), 
    ]); 
 
 
    await delay(1000); // スクレイピングする際にはアクセス間隔を1秒あける. 
  } while (true); 
 
  // ブラウザの終了. 
  console.log('----------------------------------------close'); 
  await browser.close(); 
})(); 

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)