ImportXML関数に XPath をコピペしても #N/A になる原因と対策(Google スプレッドシート)
Google スプレッドシートで他サイトの情報を取得する(スクレイピングって言うの?)のに便利な ImportXML 関数
よくある解説には、
ということで原因と対策を調べてみた
ここでは、とあるサイトの値を取得するというよくあるパターン
最初に問題となるのは、取得するサイトの文字コードが UTF-8 ではない場合
これは、相手の問題なので今回はあきらめる
次に今回の本題 XPath の値がなぜ流用できないか、というか面倒なので流用したい
XPathは、主にソース固有の場所(id等は一意なので)からの相対パスとなる
該当部分のHTMLソース
ソースを見ると
div[id='cnt01']→div[の1番目]→table[の1番目]→tr[の2番目]→td
となっている
デベロッパーツールのエレメント構成
ここで得られる XPath の情報(コーテーションは変更済み)
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td
このまま ImportXML へ貼り付けても そんなんありません(#N/A)となるが
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]
//*[@id='cnt01']/div[1]/table[1]/tbody
//*[@id='cnt01']/div[1]/table[1]
と上位へ変更してみると、突然表示されはじめるポイントがある
(もぅ、お気づきでしょう。というか画像に答え書いてあるけど)
デベロッパーツールで表示されるエレメントツリーは、ソースで省略されたタグを補完して正しい形にしたものです(こういうライブラリを用いて修正したりする)
したがって、上記例では tbody が補完されているため、そのまま XPath を利用しようとしても、そんなエレメントありませんとなるワケです
上記の例では tbody を取り去った下記の表記が答えとなります
//*[@id='cnt01']/div[1]/table[1]/tr[2]/td
つまり、ソースコードをベースに記述しなければならない ということです
よくある解説には、
Chrome なら 右クリック→検証
取得したいエレメントで Copy → Copy XPath で得られた値の ダブルコーテーションをシングルに置き換えて、=ImportXML(url, xpath)
とやれば、ホラ簡単!
みたいなのがあるけど、ほとんど取得できねぇ~~~~~~~ #N/A取得したいエレメントで Copy → Copy XPath で得られた値の ダブルコーテーションをシングルに置き換えて、=ImportXML(url, xpath)
とやれば、ホラ簡単!
ということで原因と対策を調べてみた
ここでは、とあるサイトの値を取得するというよくあるパターン
最初に問題となるのは、取得するサイトの文字コードが UTF-8 ではない場合
これは、相手の問題なので今回はあきらめる
次に今回の本題 XPath の値がなぜ流用できないか、というか面倒なので流用したい
XPathは、主にソース固有の場所(id等は一意なので)からの相対パスとなる
該当部分のHTMLソース
ソースを見ると
div[id='cnt01']→div[の1番目]→table[の1番目]→tr[の2番目]→td
となっている
デベロッパーツールのエレメント構成
ここで得られる XPath の情報(コーテーションは変更済み)
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td
このまま ImportXML へ貼り付けても そんなんありません(#N/A)となるが
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]
//*[@id='cnt01']/div[1]/table[1]/tbody
//*[@id='cnt01']/div[1]/table[1]
と上位へ変更してみると、突然表示されはじめるポイントがある
(もぅ、お気づきでしょう。というか画像に答え書いてあるけど)
デベロッパーツールで表示されるエレメントツリーは、ソースで省略されたタグを補完して正しい形にしたものです(こういうライブラリを用いて修正したりする)
したがって、上記例では tbody が補完されているため、そのまま XPath を利用しようとしても、そんなエレメントありませんとなるワケです
上記の例では tbody を取り去った下記の表記が答えとなります
//*[@id='cnt01']/div[1]/table[1]/tr[2]/td
つまり、ソースコードをベースに記述しなければならない ということです
コメント
同じ内容に困っていたので大変参考になりました。おかげで解決できました。ありがとうございます!!
お役に立てて何よりです