Google ColabとJupyter Notebookは、ローカルマシンにPythonをインストールせずに、パーススクリプトを迅速に作成して実行するための便利なツールです。しかし、クラウドノートブックには、しばしば忘れられる特性があります。それは、すべてのリクエストがGoogleのデータセンターのIPアドレスから行われるため、これらのIPはボット対策システムにすでに知られており、ほぼ瞬時にブロックされるということです。この記事では、ColabとJupyterでプロキシを正しく接続する方法、クラウド環境が課す制限、最初の50リクエスト後にパースが失敗しないようにする方法について説明します。
なぜGoogle Colabは通常のPCよりも頻繁にブロックされるのか
Colabのパースにおける主な問題は、IPアドレスの共有プールです。ノートブックを起動するたびに、Googleはクラウド範囲(AS15169など)からのIPを持つ仮想マシンを割り当てます。これらの範囲は、Cloudflare、DataDome、PerimeterXなどのほとんどのボット対策システムのブラックリストにすでに登録されています。また、Wildberries、Ozon、マーケットプレイスの組み込み保護も、瞬時にそれらを認識します。リクエストはサイトに到達することすらなく、ASN(自律システム番号)によるフィルターによって、User-Agentや動作のチェック前に遮断されます。
第二の理由は、使用の普及です。何千人もの開発者が同時にColabを通じてパーサー、ボット、MLスクリプトを実行しているため、これらのIPの評判は、あなたのリクエストのずっと前に多くのターゲットサイトで「燃え尽きて」います。たとえ10秒ごとに1回の慎重なGETリクエストを行っても、同じ範囲から1時間前に誰かが500スレッドでサーバーを叩いていたために、サイトが403を返すことがあります。
第三の理由は、ローカルで起動されたJupyterは通常この問題を抱えていないことです(通常の家庭用またはオフィス用IPを持っている場合)。しかし、ホスティングサーバー上のJupyterHubやクラウドプロバイダーのコンテナを介して作業を始めると、状況はColabと同じになります。したがって、「プロキシは必要かどうか」という問題は、クラウドノートブックにとっては明確に解決されます。プロキシなしでは、パースは最初の数回のリクエストの後にほとんど機能しません。
クラウドパースに適したプロキシの種類
プロキシの種類の選択は、何をパースしているのか、ターゲットサイトの保護がどれほど攻撃的であるかによります。ColabとJupyterでは、もう一つの注意点があります。ノートブックのセッションは時間制限があるため、長寿命のスティッキーセッションのプロキシは常に重要ではありません。むしろ、1回の実行の範囲内での接続の安定性が重要です。
| プロキシの種類 | Colab/Jupyterでの使用時期 | 特徴 |
|---|---|---|
| データセンターのプロキシ | 厳しい保護のないサイトのパース、オープンAPI、静的ページ | 高速、低価格ですが、攻撃的なサイトではASNによってブロックされることもあります |
| レジデンシャルプロキシ | Wildberries、Ozon、Avito、Google、ボット対策のあるソーシャルメディアのパース | 実際のユーザーのIP、ブラックリストに載ることは少なく、遅延が高い |
| モバイルプロキシ | モバイルサイトのパース、TikTok、InstagramのAPIを介して | 最高の信頼性ですが、コストが高く、ローテーションが遅い |
大多数のマーケットプレイスや検索エンジンのパースタスクにおいて、Colabではレジデンシャルプロキシのローテーションを各リクエストごとに組み合わせることが最適なバランスです。これにより、Googleのクラウド環境からリクエストが実行される場合でも、行動パターンによるブロックの可能性が低下します。
requestsとurllibでのプロキシ設定
Colabでのプロキシの基本設定は、ローカルのPython環境と何ら変わりありません。違いは、Colabではライブラリを通常、!pip installを介して追加する必要があることです。標準のイメージには必要なものがすべて含まれているわけではありません。
!pip install requests
import requests
proxy = {
"http": "http://login:[email protected]:9000",
"https": "http://login:[email protected]:9000"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(
"https://example.com/catalog",
proxies=proxy,
headers=headers,
timeout=15
)
print(response.status_code)
print(response.text[:500])
重要な点:Colabには永続的な設定ファイルがないため、プロキシのログインとパスワードをハードコーディングする必要があります(ノートブックを公開する際には安全ではありません)。または、google.colab.userdataを介してColabの環境変数に保存するか、Colab Secretsを介して接続することができます。これは、特に同僚とノートブックを共有する場合、コード内にパスワードを直接保存するよりも便利です。
from google.colab import userdata
proxy_login = userdata.get('PROXY_LOGIN')
proxy_pass = userdata.get('PROXY_PASS')
proxy_url = f"http://{proxy_login}:{proxy_pass}@gate.proxycove.com:9000"
proxies = {"http": proxy_url, "https": proxy_url}
ColabでのSeleniumとヘッドレスChromeを使ったプロキシ
サイトがJavaScriptを介してコンテンツをレンダリングする場合(Wildberries、Ozon、Avitoの典型的な状況)、単純なrequestsでは不十分です。ヘッドレスブラウザが必要です。Colabでは、通常、手動でインストールする必要があるSeleniumとChromiumを使用します。基本イメージには含まれていません。
!apt-get update
!apt install chromium-chromedriver
!pip install selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--proxy-server=http://gate.proxycove.com:9000')
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://example.com/catalog")
print(driver.page_source[:500])
driver.quit()
問題は、--proxy-serverフラグが直接のログインとパスワードの認証をサポートしていないことです。Seleniumで認証付きプロキシを使用するには、IP認証(ノートブックの静的IPによるホワイトリスト化が必要ですが、Colabでは不安定です。新しい実行ごとにIPが変わるため)を使用するか、プロキシの認証情報を記載したChrome拡張機能を「その場で」生成するか、selenium-wireのようなライブラリを介してプロキシトンネルを使用する必要があります。これは、認証付きプロキシを標準でサポートしています。
!pip install selenium-wire
from seleniumwire import webdriver
proxy_options = {
'proxy': {
'http': 'http://login:[email protected]:9000',
'https': 'http://login:[email protected]:9000',
}
}
driver = webdriver.Chrome(seleniumwire_options=proxy_options, options=chrome_options)
driver.get("https://example.com/catalog")
Jupyter Notebook:ローカルvsクラウド
ローカルマシンで起動されたJupyter Notebook(Anaconda経由またはpip経由で直接)は、家庭用またはオフィス用のIPアドレスを使用します。この場合、プロキシはマスキングや地理的制限の回避のためにのみ必要であり、データセンターのASNによるブロックからの保護には必要ありません。この場合の設定は、通常のPythonスクリプトと完全に同じです。requestsもSeleniumも同じで、ドライバやシステムパッケージのインストールに制限はありません。
クラウドサービスを介してJupyterを使用する場合、状況は変わります。VPS上のJupyterHub、Kaggle Notebooks、Deepnote、Binder、または企業のクラウドクラスターなどです。この場合、IPは再びプロバイダーのデータセンターに属し、Colabの問題がそのまま適用されます。Colabとの主な違いは、これらのサービスではセッション中にIPがより安定していることが多く(カーネルの再起動時に変更されないため)、プロキシプロバイダーがこれをサポートしている場合、IPによるホワイトリスト化の設定が簡単になります。
実践的な結論:パースがビジネスにとって重要である場合(たとえば、マーケットプレイスでの競合他社の価格を毎日監視する場合)、無料のクラウドノートブックを本番環境として使用するのは避け、スクリプトの開発とテストのみに使用し、最終的なパーサーを固定IPと設定されたプロキシを持つサーバーに移動する方が良いでしょう。
パースを壊すクラウドノートブックの制限
IPの評判の問題に加えて、Google Colabにはパースの安定性に直接影響を与えるいくつかの技術的制限があります:
- 非アクティブタイムアウト。 無料版のColabは、約90分のアイドル状態の後にノートブックをオフにし、12時間の連続作業の後にセッションを強制終了します。数千ページの長時間のパースは、部分に分割するか、Google Driveに中間結果を保存する必要があります。
- 新しいランタイムごとにIPが変更される。 環境を切断して再接続すると、仮想マシンのIPアドレスが変更されます。これにより、プロキシサービス側のIPによるホワイトリスト設定が壊れます。
- 発信接続の制限。 Googleは、1つの仮想マシンからの同時ネットワーク接続の数を制限しています。そのため、数十の並行リクエストを使用した攻撃的なマルチスレッド処理は、サイトのブロックではなく、Colab自体の制限にぶつかる可能性があります。
- ディスクをマウントしない限り、永続的なストレージがない。 クッキー、ブラウザのセッション、プロキシ接続のキャッシュは、毎回の再起動時に消失します。認証付きのパースには、クッキーをGoogle Driveのファイルに明示的に保存する必要があります。
- 予測不可能なネットワーク遅延。 Googleのクラウドインフラストラクチャは時折レイテンシのスパイクを引き起こし、リクエストのタイムアウトを余裕を持って設定する必要があります(標準の5-10秒ではなく15-30秒)。
これらの制限により、Colabはパーサーのロジックの開発とデバッグには優れたツールですが、長期的な本番タスクには適していません。これらのタスクには、完成したスクリプトを固定IPを持つVPSまたは専用サーバーに移動する方が良いでしょう。
プロキシのローテーションとエラー処理のループ
パースが最初のブロックで失敗しないようにするためには、プロキシを交換する再試行のロジックが必要です。以下は、Colabで直接実行できるプロキシのローテーションとエラー処理の簡単なループの例です。
import requests
import time
import random
proxy_pool = [
"http://login:[email protected]:9000",
"http://login:[email protected]:9001",
"http://login:[email protected]:9002",
]
def get_with_retry(url, max_retries=5):
for attempt in range(max_retries):
proxy_url = random.choice(proxy_pool)
proxies = {"http": proxy_url, "https": proxy_url}
try:
response = requests.get(url, proxies=proxies, timeout=20)
if response.status_code == 200:
return response
else:
print(f"試行 {attempt+1}: ステータス {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"試行 {attempt+1}: エラー {e}")
time.sleep(random.uniform(2, 5))
return None
result = get_with_retry("https://example.com/catalog")
if result:
print(result.status_code)
else:
print("すべての試行が終了しました")
大規模なカタログ(たとえば、Wildberriesの数千の商品カード)のパースには、このロジックをさらにタスクキューにラップし、リクエスト間に間隔を置き、Google Driveに中間結果をCSVまたはデータベースに保存して、Colabのセッションが切断されたときに進行状況を失わないようにします。
Colabでパーサーを実行する前のチェックリスト
- プロキシが接続され、主要なループの前に別のテストリクエストでテストされている
- プロキシのログインとパスワードがColab Secretsに保存されている(オープンコードには保存されていない)
- JSサイトには、Seleniumとselenium-wireまたは認証拡張を使用している
- コードに403/429エラー時の再試行ロジックとプロキシのローテーションがある
- 中間結果がNレコードごとにGoogle Driveに保存される
- クラウドネットワークの遅延を考慮してリクエストのタイムアウトが増加している
- リクエストの並行性が制限されており、Colabの発信接続の制限にぶつからないようになっている
- 本番タスクには、固定IPを持つ別のサーバーにスクリプトを移動することが考慮されている
結論
Google ColabとクラウドJupyterは、パーサーのロジックを迅速に開発およびテストするのに適していますが、データセンターの共有IPのため、ほぼ常に最初のステップでプロキシが必要です。攻撃的な保護のない単純なサイトにはデータセンターのプロキシで十分ですが、マーケットプレイス、検索エンジン、ソーシャルメディアのパースには、ASNフィルターにかかりにくいレジデンシャルIPやモバイルIPがより信頼性があります。
WildberriesやOzonの価格をColabから定期的に監視する予定がある場合は、レジデンシャルプロキシから始めることをお勧めします。これにより、頻繁なブロックなしで安定したアクセスが得られます。一時的なテストスクリプトには、同じ方法でrequestsやSeleniumを介して接続するデータセンターのプロキシを使用することで十分です。