
最近スクレイピングにハマリングの僕ですが、ロボットにネットサーフをさせて、自分に必要な情報だけ集められる仕組みが作れないかと日々奮闘しています。
そんな中、僕のブログで度々登場している「Spookyjs」でのクローリングですが、ページ内でjavascriptを実行させて、値を取ってくるという極めて単純な環境が手軽に構築できるので、非常に便利に使っているんですが、今回コマリングな状態(困った状態)が発生してしまいました。
ちなみに、本日のブログは、問題定義だけして解決はしていませんので、同じ問題を抱えている人は是非一緒に解決策を見つけてみましょう。
コールバックのreturn問題
非同期という言葉がだいぶメジャーになってきて、asyncオプションなどもつけているサイトをよく見かけるようになりましたが、javascriptは、ES6などから非同期を推奨しているかのような言語になってきましたね。
nodejsを使っている人などは、非同期処理でコールバックだらけのプログラムをよく見かけます。
単一処理で終わるような関数みたいな使い方ならいいのですが、今回おきた問題は、spookyjsで、ページ内のとある値を取得する際に、ボタンをクリックして画面の変化後に値を取得するといういわゆるajaxなサイトでの事ですが、
ボタンを押して1秒ほど待たないといけません。
その為、setTimeoutで時限セットして、コールバックで処理をするのですが、処理をした結果をspookyjs側にreturnする術が無いことに気がつきました・・・
細かなプログラムも事情があり書けないのですが、とにかく下の図のような状態です。

この問題わかります?
そもそも、こうした状況も特殊ではあるんですが、単一環境のプログラムで行うのであれば、グローバル変数などで受け渡せばいいのですが、違うシステムへの受け渡しで、returnでしか渡せないとなるととても問題なワケです。
無理矢理の解決法
とりあえず、僕もエンジニアの端くれ、仕事を終わらさなければいけないので、spookyjsの中で情報取得用のjavascriptにグローバル変数を作成し、スレッドを分けてwaitをかけた後に、その値を取得しに行くと言う暴挙技でなんとか値取得はできるようになりました。
おかげでスクレイピング速度を犠牲にせざるを得なくて、非常に課題の残った開発となってしまいました。
確かに非同期処理をreturnするなんて、非常に難しいプログラムなのはよく理解できるが、できないことがある自体が気に入らない。
そこで調べてみると、ES6から、promiseという命令が加わったとのことで、これを使えばなんとかできるのでは・・・とTRYしてみるも、やはりコールバックから抜け出ることができず、撃沈してしまいました。
ただ、この命令は奥が深く、try-catchなどをうまく使って、非同期をむりやり同期処理に持って行くことが可能なのかもしれないという見えないポテンシャルに期待して、もう少しお勉強しなければいけないと、自覚した段階で本日は力尽きてしまいました。
promise、IE系は見事に使えないのですが、ライブラリで補う事で、利用できなくも無いという状況のようです。
スクレイピングやるのであれば、この命令極める必要があるな!と考えたので、学習スイッチがONになってしまいました。
とにかく、非同期ングを学びングですね。
情報をお持ちの方、クレクレ〜!!!
0 件のコメント:
コメントを投稿