質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1886閲覧

puppeteerでの文字列の取得

laplade

総合スコア26

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2022/05/08 06:39

前提

puppeteer、JavaScriptを使用する。

実現したいこと

例えばカンマ区切り等で
"abc,defg,hi"
"j,k,lm"
"n,op,qr"
のように取得したい。

発生している問題・エラーメッセージ

以下のようなDOMをpuppeteerでスクレイピングしたところ、

html

1<tbody id="id-name"> 2 <tr> 3 <td id="id_a_0" class="class-name">abc</td> 4 <td id="id_b_0" class="class-name">defg</td> 5 <td id="id_c_0" class="class-name">hi</td> 6 </tr> 7 <tr> 8 <td id="id_a_1" class="class-name">j</td> 9 <td id="id_b_1" class="class-name">k</td> 10 <td id="id_c_1" class="class-name">lm</td> 11 </tr> 12 <tr> 13 <td id="id_a_2" class="class-name">n</td> 14 <td id="id_b_2" class="class-name">op</td> 15 <td id="id_c_2" class="class-name">qr</td> 16 </tr> 17</tbody>

"abcdefghi"
"jklm"
"nopqr"

のように文字列が連結されてしまいます。

該当のソースコード

index.js

javascript

1import module from 'module'; 2const require = module.createRequire(import.meta.url); 3const pModule = '../NodeModule/puppeteer@13.7.0/node_modules/puppeteer'; 4const puppeteer = require(pModule); 5 6const isDebug = true; 7(async () => { 8 const url = 'https://www.XXXXXXXXXXXXXXXXXXXXXXX/'; 9 const browser = await puppeteer.launch({ 10 headless: !isDebug, 11 devtools: isDebug, 12 args: [ 13 "--disable-gpu", 14 "--no-sandbox", 15 "--disable-setuid-sandbox", 16 "--no-first-run", 17 "--no-zygote", 18 "--single-process", 19 "--disable-dev-shm-usage", 20 ], 21 }); 22 const pages = await browser.pages(); 23 await pages[0].goto(url); 24 let data = await pages[0].$$eval('#id-name > tr', item => { 25 return item.map(data => data.textContent); 26 }); 27 console.log(data[0]); 28 console.log(data[1]); 29 console.log(data[2]); 30 await browser.close(); 31})();

試したこと

最後の「await browser.close();」の前に以下のソースを足すことで、1つ1つidを指定して個々の文字列を取得することはできました。
もっとスマートにやる方法はないでしょうか。

javascript

1 let values= []; 2 for (let i = 0; i < data.length; i++) { 3 values.push({ 4 a: await pages[0].$eval('#id-name > tr > #id_a_' + i.toString(), item => { 5 return item.textContent; 6 }), 7 b: await pages[0].$eval('#id-name > tr > #id_b_' + i.toString(), item => { 8 return item.textContent; 9 }), 10 c: await pages[0].$eval('#id-name > tr > #id_c_' + i.toString(), item => { 11 return item.textContent; 12 }), 13 }); 14 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

その後自分で色々試した結果、ずいぶんすっきりコードを書くことができました。
質問を見てくれた方、一緒に考えてくれた方、ありがとうございました。

javascript

1 let data = {}; 2 const trs = await pages[0].$$('#id-name > tr'); 3 for (const tr of trs) { 4 const d = await tr.$$eval('td', td => td.map(col => col.textContent)); 5 data[d[0]] = {b:d[1], c:d[2]}; 6 } 7 for (const key in data) { 8 console.log(key + ": b = " + data[key].b + ", c = " + data[key].c); 9 }

出力結果
XXX: b = XXX, c = XXX
XXX: b = XXX, c = XXX
XXX: b = XXX, c = XXX

投稿2022/05/10 10:47

編集2022/05/10 10:53
laplade

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問