PythonでWinHTTPRequestを叩くのだ

別に好き好んでこんな面倒な事してる訳ではもちろんない。Requestsでどうしても上手くいかなかったから仕方なくやってるのだ。テメエの事だよe-h〇n!なにやら302で2回リダイレクトさせてる上にcookie制御も相当厳密にやってる。まあそれだけならRequestsでも出来るはずなんだけど何故か上手くいかない。結局出来なかったので推測でしかないがブラウザで見るとSessionStorageを使ってるのでたぶん原因はこれじゃないか。しかし昔々大昔に作ったJScriptの奴は今でも元気に動いてるぞ?ひょっとしてWinHTTPRequestなら上手くいくのか?

WinHTTPRequestの叩き方

pywin32 libraryを使えばいいらしい。しかしlibrary名はpywin32なのにmodule名はwin32com.clientなのな。後はWinHTTPRequestのmethodを叩けばいいだけだ。

import win32com.client
winhttp = win32com.client.Dispatch("WinHTTP.WinHTTPRequest.5.1")
winhttp.Open("GET", url, False)
winhttp.SetRequestHeader("Content-Type", "text/plain;charset=Shift_JIS")
winhttp.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0 ")
winhttp.Send()

おーちゃんと200が返ってきた。後はこれをパースしてやればいいだけだ。ここはcharsetが今時Shift_JISなので一旦ResponseBodyでbyte列を取得しておいてそれをtextにしてやらねばならない。しかしこのResponseBodyがなにやらmemoryview型とやらで返ってくる。byte型じゃないのか。

<memory at 0x000001A96428CF40>

必死に検索すると要するにCのポインタを返してるのね。つまりこれメモリのアドレスか。しかしサラッと書いたけど調べて理解するのに半日程かかったよ。memoryview() in Python辺りが英語だけど分かりやすかった。

html = winhttp.ResponseBody.tobytes().decode("shift_jis")

後はこのhtmlをBeautifulSoupに食わせて処理するだけ。しかしそもそも何故ResponseBodyがmemoryview型で返るのかは不明。