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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

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

Q&A

解決済

2回答

1322閲覧

複数のWEBページの情報を取得してくるクローラを作りたい

kaitotokai

総合スコア59

Node.js

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

0グッド

0クリップ

投稿2018/06/12 07:12

複数のWEBページの情報を取得してくるクローラを作りたい。
http://liginc.co.jp/programmer/archives/4848 を見ながらクローリングのためのコードを書いている。

// Initialize instance var sequelize = require('sequelize'); // Connect to database var connection = new sequelize('データベース名', 'ユーザ名', 'パスワード', {オプション: '値'}); // Define models var sites = connection.define('sites', { url: sequelize.TEXT, title: sequelize.STRING }); //Initialize instance var request = require("request"); var cheerio = require("cheerio"); // Define request url var requestUrl = "http://www.google.com"; // Send http request request({url: requestUrl}, function(error, response, body) { // If request succeed if (!error && response.statusCode == 200) { $ = cheerio.load(body); // Create cheerio instance // Get response data var url = response.request.href; var title = $("title").text(); console.log(url); console.log(title); // Create new instance var site = sites.build(); // Set fields site.url = url; site.title = title; // Save to database site.save() .success(function(anotherTask) { console.log('Succeed'); }) .error(function(error) { console.log(error); }); } // If error occured else { console.log("--------------------------------------------------"); if (error && "code" in error) { console.log("Error Code:" + error.code); } if (error && "errno" in error) { console.log("Error No:" + error.errno); } if (error && "syscall" in error) { console.log("Error Syscall:" + error.syscall); } if (response && "statusCode" in response) { console.log("Status Code:" + response.statusCode); } } });

と書いてある中に、

var requestUrl = "http://www.google.com";

とURLが書いてあるが、
複数のWEBページの情報を取得してくるクローラを作りたい場合にはどうしたら良いか?
例えば、nifty ( https://www.nifty.com/ )やlivedoor( http://www.livedoor.com/ )のサイトからもタイトルを取得してきてその情報をDBに入れるようにしたい。しかし、googleとniftyとlivedoorのwebのhtml構造は違う。
質問したい点は、
・取得してきたいWEBページの個数分スクリプトを作った方がいいのか?
・複数のURLをクローリングしたい場合、効率的にクローリングする方法はあるのか?
という点である。
ちなみに、1日1回指定のURLからクロールしたい。

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

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

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

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

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

guest

回答2

0

ベストアンサー

クローラでもクローリングでもなくスクレイピングですね?

当然サイトの数だけ「どこを取り出すか」の情報が必要で、
サイトの数だけアクセスする必要があります。
しかしハードコーディングしてしまうと対象サイトに変更があるたびに、
コードを書き直す必要がありますし、サイトの数だけスクリプトを作るのもスマートではありません。

私の場合は「どこを取り出してどう処理するか」を別に簡単なスクリプト的ファイルにして、
そのファイルを読み出して処理をするプログラムを書いて使っています。
(VBAで書いてるので参考部分を出せませんが。)

スクリプト的なものを考えなくとも、
Node.jsであればevalでクローリング部分だけ書いたファイルを読むとかって手もありますね。

効率的にクローリングというのは、CPU効率であったり総処理時間の話でしょうか?
サイトの件数分マルチスレッドで並列処理するのが高速でしょうか。

投稿2018/06/12 14:15

shinobu_osaka

総合スコア456

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

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

kaitotokai

2018/06/12 14:54

ありがとうございます。とても参考になります。「どこを取り出してどう処理するか」を別に簡単なスクリプト的ファイルにして、と書かれたのに1点質問があります。サイトの数だけどこを取り出してどう処理するかのメソッドを作りそのメソッドたちを1つのスクリプトにまとめ、それらのメソッドを別のファイルで呼び出してくる、と言う意味でしょうか?
shinobu_osaka

2018/06/12 17:34

えーと、私の場合ですが、 思いっきり独自仕様ですので参考になるかどうかですが、設定ファイル内に、 [001] 000=サイト名 // 識別用サイト名 001=0 // ログインフォームの番号 002=3 // ログインフォームのIDのinputボックスの番号 003=4 // ログインフォームの PW inputボックスの番号の番号 004=6 // ログインサブミットボタンの番号 005=https://xxx.xxx.xxx/login.php // ログインURL 006=https://xxx.xxx.xxx/logout.php // ログアウトURL 007=https://xxx.xxx.xxx/view.php?p=001 // データをゲットするURL=データをゲットするURL 008=ID // ID 009=PW // PW 010=data001,TABLE,1,TR,1,TD,1 // 取り出しデータ位置 011=data002,TABLE,1,TR,1,TD,2 // 取り出しデータ位置 012=data003,TABLE,1,TR,2,TD,1 // 取り出しデータ位置 013=data004,TABLE,1,TR,2,TD,2 // 取り出しデータ位置 999=Logout,Login(001,002,003,004,008,009),Dataget(010-013),Logout … という感じのが複数記載してありまして… なくなるまで順次読み出し処理をしてます、 全部変数に読み出した上でスクリプトに書いてある処理のルーチンを順番に回す感じですね。 どんな感じに設計するかはこの設定ファイルの記載の楽さと高性能さに関わってくるので、 センス次第ではありますよね。 JSON形式とかつかっちゃうと手書きが困難になるのであんまりおすすめできないかな。 自分専用でかつ安全なサーバーで動かすのであれば単純に var connection = new sequelize('データベース名', 'ユーザ名', 'パスワード', {オプション: '値'}); // Define models var sites = connection.define('sites', { url: sequelize.TEXT, title: sequelize.STRING }); //Initialize instance var request = require("request"); var cheerio = require("cheerio"); ..... とか書いて読み出してevalするのもアリかと。
kaitotokai

2018/06/13 12:25

ありがとうございます!!勉強になりました!
guest

0

Octoparseというスクレイピングツールを使っています。

複数のWEBページの情報を取得するチュートリアルもあります。
https://www.octoparse.jp/tutorial/extract-multiple-pages-through-pagination/

1日1回のクローリングもできます。

投稿2018/06/13 01:47

編集2019/03/12 02:13
Yuki-Sakuraba

総合スコア163

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問