やりたかったこと
あるサイトからテーブルをスクレイピングしたかった。
その際、普通はテーブルにIDやClass指定がしてあるので、それをもとにスクレイピングする。しかし今回の場合は、スクレイピングするtr tdにクラス名やIDが指定されていなかったので、それらの値から取得できなかった。
さらに、その場合だと、要素の数を指定してデータを取ることができるのだか、テーブルの中には取得したい複数のページのうち、存在したり存在しなかったりするカラムがあるので、順番でとると一つ抜けると取得したいデータが全部変わってしまう。
Xpathを利用してもやはり同様の理由でDOM構造が変わってしまうので、取得できなかった。
#案件— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
取得するページによってテーブル数が違うから、そうするとその例外処理をしなければいけないな。テーブルのthのタイトルから取得すれば、一意であればテーブルのカラム数が変わったとしても対応できそう。
#案件— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
なので、tagとclassとid意外で、あるカラムが存在するかを調べたい。
ただしそのカラムには一意のclassやcssを設定されていないので、その場合だとおそらく中のtextで検索する必要があるけど、cssからtext検索はできない。xpathでやろうかと考えたが、dom構造が変わるので一般化できない。
そこで、特定のtr要素のテキストの値が一致したものだけを取得する方法を、今回は試行錯誤して取得した。検索を行うのはCSS Selectorからは難しそうで、Xpathしかできないよう。なので、なんとか無理やりjavascriptを利用して取得することにした。
Javascriptを実行するコードを、string上に入れようとすると、シングルクオートの中のダブルクオートの中に値を入れる必要があるので、それは不可能っぽいことがわかった。なので別の手段を使う必要があると感じた。format記法でなんとかなるやろと思ったけど、結局format記法でやったとしても挿入するのはダブルクオートかシングルクオートなので意味なくて失敗した。
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
つまったところ
Javascriptを実行するコードを、string上に入れようとすると、シングルクオートの中のダブルクオートの中に値を入れる必要があるので、それは不可能っぽいことがわかった。なので別の手段を使う必要があると感じた。format記法でなんとかなるやろと思ったけど、結局format記法でやったとしても挿入するのはダブルクオートかシングルクオートなので意味なくて失敗した。
#案件— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
ダブルクオートの中にシングルクオートをいれて区別するのはわかるんだけど、さらにシングルクオートの中になんらかのクオートを含めなければならない場合どうすればいいんだろう。 pic.twitter.com/Arm4swcj6G
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
困っていてツイートすると、このようなアドバイスをいただいた。
なので試してみた。最初やったこと。これは当たり前だけど、jsを実行するのにjs内部にトリプルクオート入れて失敗するというあほらしい失態。
その後
のようにやっていたが、空の値が返ってきて失敗。
なんでやろって考えて悩んだ結果解決方法がわかった。
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
なので試してみた。最初やったこと。これは当たり前だけど、jsを実行するのにjs内部にトリプルクオート入れて失敗するというあほらしい失態。
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
その後
— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
のようにやっていたが、空の値が返ってきて失敗。
なんでやろって考えて悩んだ結果解決方法がわかった。
#案件— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
seleniumのexecute_scriptは何かリターンするメソッドなのだろうか。
jsの実行をさせているから、もしかしてなかでjqueryのtext()をやっても、それをリターンしてくれてないのかな。
#案件— Dai Kawai@RubyPython (@never_be_a_pm) January 13, 2018
解決。仮説は当たっていた。
おそらくだけど、seleniumのexcecute_scriptはvoidっぽいメソッドで、returnを返すわけではない(普通にjavascriptを実行するだけのメソッド)。なので、returnまで含めてあげたらスクレイピングした結果を取得できた。 pic.twitter.com/AHYpGCZURG