puppeteer + jsdomでTableを取得して加工する方法についてのメモです。
例
例として、以下の気象庁のページを使います。
上のぺージを開くと、以下のような画面が開くのですが

ここではtableを取得して、赤枠部分だけが表示されるように加工します。
以下、ソースです。
これを実行すると、以下のようなtableのHTMLを取得できます。
| 月 | 気温(℃) | ||||
|---|---|---|---|---|---|
| 平均 | 最高 | 最低 | |||
| 日平均 | 日最高 | 日最低 | |||
| 7.1 | 11.1 | 3.7 | 18.6 | 0.6 | |
| 8.3 | 13.3 | 4.0 | 18.2 | -2.1 | |
| 10.7 | 16.0 | 6.2 | 24.6 | 0.7 | |
| 12.8 | 18.2 | 7.9 | 24.2 | 5.3 | |
| 19.5 | 24.0 | 15.6 | 28.7 | 10.7 | |
| 23.2 | 27.5 | 19.8 | 32.6 | 17.1 | |
| 24.3 | 27.7 | 21.8 | 32.5 | 17.4 | |
| 29.1 | 34.1 | 25.3 | 37.3 | 21.8 | |
| 24.2 | 28.1 | 21.5 | 35.1 | 14.7 | |
| 17.5 | 21.4 | 14.4 | 26.7 | 9.2 | |
| 14.0 | 18.6 | 10.1 | 24.9 | 5.2 | |
| 7.7 | 12.3 | 3.7 | 17.2 | -0.6 | |
以下、ソースについての補足です。
Array.from
Array.fromでHTMLCollectionなchildrenを配列に変換しているのは、ループ文を使うためです。
参考:JavaScript NodeList, HTMLCollection は配列(Array)ではない – かもメモ
参考:JavaScriptでNodeListやHTMLCollectionを配列に変換する方法
jsdomを使わない方法
jsdomを使わなくても
await page.$eval("#tablefix1", (e) => e.outerHTML);
の部分で
await page.$eval("#tablefix1", (e) => {
//ここでtableを取得&加工する処理をすべて書いてしまう
);
という感じに書くことでjsdomを使わずに書けます。
ただ、この方法だと(おそらく)事前に定義した関数などが使えなくなってしまうというデメリットがあると思われます。
(もし間違ってる場合はご指摘いただけると非常に嬉しいです・・・!)
colspan と rowspan
今回の例のように、行や列を結合されていると、加工するのがちょっとややこしいです。
なので今回は事前に設定した「行」「列」だけが抜き出されるようにしています。
それを設定しているのがtargetRowsAndColumnsという変数です。
加工してから取得 or 取得してから加工
tableを抜き出す方法としては
- ターゲットのtableから必要なデータだけを抜き出し、新たなtableを作成する方法
- ターゲットのtableから不要なデータを削除して、新たなtableを作成する方法
の2種類があると思うのですが、今回は前者です。
削除するデータが少ない場合は、後者の方が良いかもしれません。
おわり
コメント