Tor Browser を活用して requests (python) してみる話

# はじめに

Apple の [iCloud Private Relay](https://www.apple.com/privacy/docs/iCloud_Private_Relay_Overview_Dec2021.PDF) は素晴らしい（唐突）。
iCloud 課金勢の私も試しに使い始めてみたところ、十分に実用できる性能で感動してしまい、今や常用ユーザーとなってしまった。

この弊害として、自宅のPCからブラウジングしている時に、接続元を明かしてインターネットを徘徊することが、なんとなく裸で外を歩き回るかのような気持ち悪さを感じるようになってしまった（個人の感想です）。

そのような心変わりがあってからか、長年塩漬けにしていた Tor Browser を引っ張り出して来て、最近はプライベートブラウジングしたい時に、Tor Browser を使うようになった。
ここまで神経質になってくると、今度は普段使っている Python Requests モジュールからの通信も、なんとなくプライベートさを出したくなって来てしまった。

ちなみに、 Tor Browser を普段使っている皆様におかれては、特段新たな環境を用意することなく、簡単に上記の目的を達成できてしまうので、本記事ではその点を紹介しようと思う。

# 想定読者

* Tor経由の通信プログラムを書きたい人
* 既にTor Browserを導入している人

# ざっくり結論

Tor Browser を起動して、Tor Network に接続すると、バックグラウンドでTor Proxyが起動する。
SOCKS5 プロキシで動いてるので、そのプロキシを通せば Tor ネットワークに出られる。

この辺の仕組みが分かれば、どのようなプログラムにおいても簡単に Tor へ出られるはずである。
特に JTC 勤務の各位におかれては、このような実装は造作も無いことだろう。

### 参考情報

##### Tor Browser 起動画面

Tor Browese を立ち上げると、Tor への接続ダイアログが立ち上がる。ここで Connect ボタンを押すと、Tor Proxy が立ち上がり、Tor への接続が開始される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3405393/06af9fab-5ea8-c554-f5d6-61d3dafb5470.png)

Connect ボタン押下後に、Tor Network へ接続中の様子。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3405393/9986b809-e804-7561-83f7-5b626ad114e9.png)


##### Tor Proxy のログ表示画面。

Tor Proxy のログは、ブラウザの設定画面から確認できる。
Settings -> Connection -> Advanced View the Tor logs -> View Logs で確認可能である。
後述の SOCKS5 プロキシサーバーの待ち受けポートは、Opening Socket Listener で表示されているポートとなるため、このポートは確認しておくことが望ましい。（通常はデフォルト設定ポートかと思われるが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3405393/04c9821d-ab92-fe62-427e-886903279d43.png)


# Python Requests モジュールの例

ざっくり結論で皆様に伝えたいことは、ほぼ言ってしまったのだが、折角なので Python の Requests モジュールでの例を示しておく。

## SOCKS Proxy を有効にする

Requests モジュールの[ドキュメント](https://requests.readthedocs.io/en/latest/user/advanced/#socks)によれば、SOCKS Proxy を利用する場合は、依存パッケージをインストールする必要がある。

pipで依存パッケージをインストールする。

```bash
$ python -m pip install requests[socks]
```

socks 依存パッケージをインストールできていないと、SOCKS Proxy を経由しようとすると以下のようなエラーとなる。

```
  File "C:\...(中略)...\Python\Python310\lib\site-packages\requests\adapters.py", line 61, in SOCKSProxyManager
    raise InvalidSchema("Missing dependencies for SOCKS support.")
requests.exceptions.InvalidSchema: Missing dependencies for SOCKS support.
```

## 自分のIP/Whoisを確認

requests モジュールを使って、まずは自分のIPと Whois を確認してみましょう。
Python requests から、[IPWhois](https://ipwhois.io/) のAPIを利用して確認を行う。コードは以下の通り。

```python
import requests
import json

req = requests.get(
    url='http://ipwho.is/'
)
print(json.dumps(json.loads(req.text),indent=2))
```

実行すると、あなたのIPアドレスが表示されるはず。

## Tor経由でIP/Whoisを確認

まずは、Tor Browser を起動して、Tor Network に接続する。

requests で呼び出す際は、Tor が待ち受けている socks proxy を設定する。
Tor のデフォルト設定では、待ち受けアドレスは 172.0.0.1:9150 になっている。（先述の Tor Proxy のログ確認方法からポートを調べることもできる）

デフォルトポートを利用する場合は、以下のコードになる。

```python
import requests
import json

proxies = {
    'http': "socks5h://127.0.0.1:9150",
    'https': "socks5h://127.0.0.1:9150"
}

req = requests.get(
    url='http://ipwho.is/', proxies=proxies
)
print(json.dumps(json.loads(req.text),indent=2))
```

実行すると、Tor の出口ノードのIPアドレスと whois 情報が出力されるはず。
出口ノードの情報が表示されているということは、適切に Tor を経由してインターネット出来ていることが分かる。

# Pythonでのrequests以外の使い方

素晴らしい先人の記事として、PySocks を利用したやり方もあるので、参考までにご紹介。

* [PythonでTorを用いてスクレイピングする](https://qiita.com/Michinosuke/items/81f4b893bb1406162ab3)

むしろこちらのやり方のほうが汎用性高いかも。

# おわりに

ここまで Tor の話題でお送りしましたが、やはり [iCloud Private Relay](https://www.apple.com/privacy/docs/iCloud_Private_Relay_Overview_Dec2021.PDF) が最高！