動いてたコードが動かない...?!でも僕何もしてないもん!!!
昔書いたスクレイピングのためのプログラムが突然動作しなくなりました.
確認すると,webページをダウンロードする箇所でexceptionをもらっている様子.具体的には,403エラーをサーバーから返されたようです.
このページでは,一部のwebサイトはChromeなどを使用するとアクセスできるが,自前のプラグラムでそのwebページのhtmlをダウンロードしようとすると,403でダウンロードできないことが述べられています.
本投稿では,そのようなページをなんとかダウンロードできるように頑張った結果を報告します.とりあえず,ここで達成されていなかった,https://www.nike.com/jp/
のページをダウンロードすることを目標にします.
また筆者はネットワーク雑魚勢なので,問題があればご指摘お願いします.
403されたコード
以下のコードでは,DownloadString
の引数にhttps://www.google.co.jp/
を指定すると問題なく実行できます.
一方https://www.nike.com/jp/
を指定すると,403をもらいます.
using(varwc=newSystem.Net.WebClient()){varhtml=wc.DownloadString(@"https://www.google.co.jp/");// OK!!!//var html = wc.DownloadString( @"https://www.nike.com/jp/" ); // NG...Console.WriteLine(html);}
解決策
HTTPのヘッダに,何かしら指定しました.
using(varwc=newSystem.Net.WebClient()){wc.Headers.Add("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");varhtml=wc.DownloadString($@"https://www.nike.com/jp/");//OK!!!Console.WriteLine(html);}
このソースコードでは,keyがaccept
,valueがtext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
という謎のヘッダをリクエストに取り付けました.
このヘッダの正体は,Chromeでhttps://www.nike.com/jp/
にアクセスするときに使用されていたヘッダの一部を借用したものです.どのようなヘッダが使用されていたかは,Chromeのデベロッパーツールを使用すると確認できます.すなわち,Chromeでアクセスできるんだからその状況を再現してやろう,というコンセプト.
スクショからはいろいろなヘッダが取り付けられていたことが確認できますが,https://www.nike.com/jp/
のページをダウンロードするだけなら,accept
ヘッダだけつけておけば問題ないようです.他のwebページでは必要なヘッダは異なるはずです.どのヘッダを取り付けると403を回避できるかは,片っ端からヘッダを付けたり外したりするとわかります.パワープレイ.
結論
適当なヘッダを取り付けておけば,とりあえずwebページは落ちてきます.
リクエストを送るwebサーバーごとに,リクエストに取り付けておくべきヘッダはもちろん異なるはずです.うまく対処しましょう.
リクエストにヘッダを取り付けない状態ではサーバーが403を返す理由を考えると,機械的にアクセスするのは避けるべきなのかなあとも思ったりはします.