空談録

世界で5人くらいに役立ちたい

Power QueryがURLを認識できないとか言い出した時

誰もこのエラー踏んでないなと思ったらそりゃ誰も踏まないわってなった。

アズールレーンというゲームをしていると自分の手持ちがよくわからなくなったので、Excelでキャラのレベルを管理しています。
ただ、わざわざキャラ一覧とかつくりたくないのでPower QueryでWikiのページから拾ってきてそこにレベルを書き足して管理してました。

ところがどっかのタイミングでなんか見かけないエラーが出てきたという話です。

使ってたクエリ

めっちゃ普通のクエリです。途中まで使えていたのが謎。
参照してたページは キャラクターリスト - アズールレーン(アズレン)攻略 Wiki

let
    Source = Web.Page(Web.Contents("http://azurlane.wikiru.jp/index.php?%A5%AD%A5%E3%A5%E9%A5%AF%A5%BF%A1%BC%A5%EA%A5%B9%A5%C8")),
    Data = Source{2}[Data],
    #"Replaced Value" = Table.ReplaceValue(Data,"C","20",Replacer.ReplaceText,{"No."}),
    #"Changed Type" = Table.TransformColumnTypes(#"Replaced Value",{{"No.", Int64.Type}, {"名前", type text}, {"陣営", type text}, {"レア度", type text}, {"艦種", type text}, {"建造時間", type text}, {"耐久", Int64.Type}, {"装甲", type text}, {"装填", Int64.Type}, {"火力", Int64.Type}, {"雷装", Int64.Type}, {"回避", Int64.Type}, {"対空", Int64.Type}, {"航空", Int64.Type}, {"消費", Int64.Type}, {"速力", Int64.Type}, {"声優", type text}})
in
    #"Changed Type"

ほぼ未加工(どっかのタイミングでテーブルが参照できなくなったのでそこだけ触ってます)

最近こんなエラーが出てきた

ところがある日更新しようとしたらこんなのが出てくるようになりました。

f:id:fantasticswallow:20180317104627p:plain

DataFormat.Error: The supplied URL must be a valid 'http:' or 'https:' URL.
Details:
javascript:false

いやどう見てもhttpで始まってるんですが…。

ぐーぐるで同じようなの探してたんですが、ゼロ幅スペースが~的なのが出てくるだけで答えにたどり着けず。
UserAgent偽装とかやっても取れないので割とお手上げでした。

javascript:falseから考えてみる

しかし今更別サイトから拾うように~って思っても面倒だしということで何とか直してみます。

まずこの現象自体は何起因で起こってるのか切り分けます。
・Webページに接続できていない
・Webページには接続できているがデータを返してもらえない (UserAgentなどでブロックされている)
・Webページに接続できてデータが返ってきているが、テーブルの中身が存在していない。(別のjsonで返してくるなど)
・Webページに接続できてデータがもらえているがパースができない

概ねこの4パターンかと。
とりあえず一番上だった場合はもはやお手上げなのでそこから見ていきます。

Web.Contents関数がbinaryのデータを返すため、接続できているか自体はこれだけで判別できます。
本当に落ちてきてるかも見るためにBinary.ToTextで文字列に変換しておきます。

Binary.ToText(Web.Contents("http://azurlane.wikiru.jp/index.php?%A5%AD%A5%E3%A5%E9%A5%AF%A5%BF%A1%BC%A5%EA%A5%B9%A5%C8"))

f:id:fantasticswallow:20180317110232p:plain

こんな感じでひとまず何かしら落ちてきていることがわかります。つまり接続自体は問題ないということに。

残る問題を切り分けていきます。3つ目についてはブラウザの開発者ツール使えば返ってきてるか見えるのでそこで判別。
めんどいので画像は割愛。こちらも含まれています(というか入ってなかったら今までどうやってたの状態)

というわけでパースに失敗している説が濃厚になってきました。
そのため先ほどのBinaryの中身を眺めてみましょう。尻切れとかかもしれませんし。
Text.FromBinaryで文字列に展開します。

f:id:fantasticswallow:20180317110938p:plain

ペロッ…これは…文字コード…!

この結果を見る限りどうも自動文字コード判定で何か違う文字コードを選択している可能性が高いです。
ならば文字コードを正しく選択すればうまくいくのでは…!?ってことでやってみましょう。

Text.FromBinaryの第2引数に文字コードを指定することができるのでここに数字を入れます。
魔法の数字についてはMSDNから拾ってきます。
Encoding クラス (System.Text)

(Power Queryは中身はC#なのでSystem.Text.Encodingの値が使えます)

wikiページの文字コードは開発者ツールで見つけましょう。charset=euc-jpとのことなので20932が第2引数になります。

f:id:fantasticswallow:20180317112415p:plain

無事に読めました。これであとはWeb.PageでパースすればOKです。

= Web.Page(Text.FromBinary(Web.Contents("http://azurlane.wikiru.jp/index.php?%A5%AD%A5%E3%A5%E9%A5%AF%A5%BF%A1%BC%A5%EA%A5%B9%A5%C8"), 20932))

これで無事に取れるようになったので、Source部分を差し替えればうごきます。


というわけでいわゆるCJKな言語の問題でした。向こうはほぼ起こらないしなぁ。。。

最近Go言語的なのを触ってますがなかなか難しいですねぇ。
全部C#にしたいきもちが出てきてしまう……。
そういうのにBlazorとかいいんだろうなと思ったり思わなかったり。

この辺で