0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

node.js上のpuppeteerライブラリでHTML表の全行の要素をスクレイピングする

Last updated at Posted at 2021-01-03

ターゲット

スクレイピング対象のターゲットHTMLは以下のようなWebページです。あるプロジェクトのメンバー一覧です。

スクリーンショット 2021-01-04 0.08.30.png

結論

HTML表の行数を求めるには、行を表すアイテムセレクター #content > center > table > tbody > tr をブラウザの page オブジェクトの $$() メソッドに指定します。そうしてメソッドの戻り値の length プロパティがHTML表の行数となります。

HTML表の行数を求める
let numOfAccount = 
      ( await page.$$( '#content > center > table > tbody > tr' ) ).length

求めた行数を変数 numOfAccount に格納して利用します。

HTMLの構造

一覧表はcenterタグ内にtableタグがあり、さらにtableタグ内にtbodyタグがあり、さらにtbodyタグ内にtrタグがあります。このtrタグ内の情報をスクレイピングします。

スクレイピング対象のターゲットHTML
<center>
  <table border="1" bgcolor="white" rules="all" class="TableColor">
    <tbody>
       <tr bgcolor="#eeeeff" class="TableHeadingColor">
         <th>アカウント</th>
         <th>氏名</th>
         <th>メールアドレス</th>
         <th>所属</th>
         <th>ロール</th>
         <th>アクセス表示</th>
         <th>表示順</th>
         <th colspan="2">状態変更</th>
       </tr>
       <tr bgcolor="#ffffff">
         <td>
           <a name="9999999"><img src="../images/user/invisible.png"></a>
           <a href="javascript:void(0)" class="userEditAnchor" data-account="9999999" data-role="2">9999999</a>
         </td>
         <td>帆花 風彦</td>
	<td>
          <a href="mailto:hoge_fuuhiko@baaboo.co.jp">hoge_fuuhiko@baaboo.co.jp</a>
        </td>
        <td>馬場時時開発本部</td>
        <td>開発メンバー</td>
        <td class="textCenterTd"><input type="checkbox" class="showaccessmode" name="access_9999999" value="1" checked="">
         </td>
         <td>
           <span id="oarea_9999999">
             <input type="hidden" name="order_9999999" value="1" id="order_9999999">
             <input type="button" class="disporderbtn" name="order_0272054" value="1">
           </span>
           <input type="hidden" name="dborder_9999999" value="1">
	</td>
         <td>
           <input type="button" id="invalid_9999999" name="label" value="無効">
         </td>
	<td>削除不可</td>
      </tr>
  ・・・・・・・・・・以下表の行数分<tr>タグを繰り返し・・・・・・・・・・
    </tbody>
  </table>
</center>

アイテムセレクター

スクレイピング対象のターゲットHTMLの tr タグのアイテムセレクターはタグの入れ子構造から

  • #content > center > table > tbody > tr

となります。

そこで、 TARGET オブジェクトのプロパティ

  • TARGET.project.userList.itemSelector.trTag'#content > center > table > tbody > tr'

と定義して利用することにします。

オブジェクト定義
const TARGET = {
  projectList: []
  ,
  url: {
      home: 'https://target.hoge.jp/'
    , project: {
        urlMask: '%ProjectNo%'
      , alllist: 'https://target.hoge.jp//manage/list.php'
      , userList: 'https://target.hoge.jp/users/list.php?project_id=%ProjectNo%'
    }
  }
  ,
  project : {
    allList: {
        rowNo: { top: 2 }
      , colNo: { id: 2, name: 3, team: 4 }
      , itemSelector: {
          rowNoMask: '%rowNo%', colNoMask: '%colNo%'
          , trTag: '#content > form > center > table > tbody > tr'
          , aTag: ' > a'
          , template: {
              row: '#content > form > center > table > tbody > tr:nth-child(%rowNo%)'
            , col: ' > td:nth-child(%colNo%)'
          }
        }
    }
    ,
    userList: {
        topRowNo: 2
      , colNo: { account: 1, name: 2, mailAddress: 3, belongs: 4 , role: 5 } 
      , itemSelector : {
          rowNoMask: '%rowNo%', colNoMask: '%colNo%', accountMask: '%account%'
        , trTag: '#content > center > table > tbody > tr'
        , aTag: ' > a.userEditAnchor'
        , invalidButton: 'input[id=invalid_%account%]'
        , searchButton: 'searchbtn'
        , template: {
              row: '#content > center > table > tbody > tr:nth-child(%rowNo%)'
            , col: ' > td:nth-child(%colNo%)'
          }
      }
    }
  }
}

HTML表の行数の使い方例

page.$$( TARGET.project.userList.itemSelector.trTag ) ).length により求められたHTML表の行数を格納した変数numOfAccountを最大値にしてforループで繰り返して、HTML表に格納されたデータをスクレイピングします。ここでは、アカウント氏名メールアドレスロールをスクレイピングしています。この処理を以下のgetAccountList()関数で実装します。

getAccountList()
const getAccountList = async function( page, accountList ) {
  console.log( '..... getAccountList() .....' )
  let [ account, name, mailAddress, belongs, role ] = [ '', '', '', '', '' ]
  let accountObj = {}
  try {
    let numOfAccount = 
      ( await page.$$( TARGET.project.userList.itemSelector.trTag ) ).length
    
    console.log( '<------ Project Member List Start ------>' )
    for( let rowNo = TARGET.project.userList.topRowNo; rowNo <= numOfAccount; rowNo++ ) {
      [ account, name, mailAddress, belongs, role ] = await getAccountItem( page, rowNo )

      if( account == '' ) continue

      accountObj = {    アカウント    : account
                      , 氏名       : name
                      , メールアドレス: mailAddress
                      , ロール      : role
                    }
      accountList.push( accountObj )
    }
  } catch( error ) {
    console.log( '------> Project Member List End Over <------' )
  } finally {
    if( Object.values( accountObj ).length == 0 ){
      accountObj = {    アカウント   : ''
                      , 氏名       : ''
                      , メールアドレス: ''
                      , ロール      : ''
                    }
      accountList.push( accountObj )
    }
    return accountList
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?