DrissionPageは、Chromium系ブラウザの操作とHTTPリクエストによる取得を1つのAPIで扱えるPythonライブラリです。WebDriverを介さずChrome DevTools Protocol(CDP)でブラウザに直接つながるため、ChromeDriverの版合わせが要りません。
ネット上の解説は今も ChromiumPage や WebPage で書かれたものが大半ですが、作者は4.1から Chromium() を入口にするよう呼びかけており、5.0のベータでは両クラスが削除されました。この記事のコードは、安定版4.1.1.4とベータ版5.0.0b1の両方で、Chrome 155のヘッドレスモードにより2026-10-24に実行して出力を確かめたものです。
まとめ:DrissionPageを使う前に押さえる要点
- 現行の安定版は 4.1.1.4(PyPI公開2026-05-27)。5.0は 5.0.0b1(2026-08-20)のままベータ版です。
- 新しく書くコードは
from DrissionPage import ChromiumとChromium().latest_tabで始めます。5.0.0b1ではfrom DrissionPage import ChromiumPageが ImportError になります。 - ライセンスは独自条項で、権利者の許可なく商用に使うことを禁じています。社内ツールや受託案件で使う前に、作者の許諾を得るか別のライブラリを選ぶ必要があります。
- 別オリジンのiframe内の要素は、4.1.1.4ではタブから直接探せず
get_frame()を経由します。5.0.0b1ではタブから直接取れました。 - テキストの部分一致(記号なし・
text:)は<script>の中身も拾います。タグを添えてtag:p@@text():…と書くのが確実です。 - 対応ブラウザはChromeやEdgeなどChromium系とElectronアプリのみです。Firefoxの確認にはSeleniumかPlaywright、Safari本体の確認にはSeleniumを選びます。
DrissionPageの位置づけ:CDP直結のブラウザ操作とrequests系の取得の統合
DrissionPageは開発者g1879氏が2020年から公開しているライブラリで、ソースコードと利用条件は公式GitHubリポジトリで確認できます。初期はSeleniumの上に作られていましたが、現在はSeleniumに依存せず、CDPでブラウザに直接つながります。
動作要件は公式ドキュメントのインストールページで、OSがWindows・Linux・Mac、Pythonが3.6以上、ブラウザがChromium系(ChromeやEdge)とElectronアプリと定められています。同じく公式の「准备工作(準備)」ページには、旧版では一部の機能が使えないため、版番号100以上のブラウザを使うよう注意書きがあります。
| 版 | PyPI公開日 | 位置づけ |
|---|---|---|
| 4.1.0.0 | 2024-09-17 | Chromiumクラスを入口に変更 |
| 4.1.1.4 | 2026-05-27 | 現行の安定版 |
| 4.2.0b20 | 2026-06-18 | 4.2系ベータの最終 |
| 5.0.0b1 | 2026-08-20 | ChromiumPage・WebPageを削除 |
各版の公開日はPyPIのリリース履歴で確認でき、2026-10-24時点で5.0.0b1より新しい版は出ていません。pip install DrissionPage で入るのは安定版の4.1.1.4で、ベータ版を入れるには --pre を付けるか DrissionPage==5.0.0b1 と版を指定します。
商用利用の条件:独自ライセンスで権利者の許可が必要
DrissionPageはMITやApacheのようなオープンソースライセンスではありません。リポジトリのLICENSEファイルは中国語と英語の独自条項で、GitHub上の識別子も「NOASSERTION」(既知のライセンスに該当しない)と表示されます。英語版の条文は次のとおりです。
An individual or organization may not use the project's source code or binary form for commercial purposes without authorization from the copyright holder.
個人としての利用・再配布も「学習と合法的な非営利目的」に限られ、さらに次の条件を1つでも破ると許諾が自動的に失効すると定めています。
- 現地の法律や倫理に反するおそれのあるプロジェクトに使わない
- 他人の利益を損なうおそれのあるプロジェクトに使わない
- 攻撃や嫌がらせに使わない
- Robots協定(robots.txt)に従い、法律やrobots.txtが許さないデータを収集しない
会社の業務システムや受託開発の納品物、有償サービスのデータ収集に組み込む場合は、作者(公式ドキュメントに記載の連絡先 [email protected])から許可を得るのが前提です。許諾を取る手間をかけられないなら、Apache-2.0で公開されているSeleniumかPlaywrightを選びます。robots.txtの順守が許諾条件に含まれている点も、収集対象を決める段階で効いてきます。スクレイピング全般の法務の判断はスクレイピングとは?クローリング・APIとの違いと実装・法務の判断を解説で整理しています。
インストールとブラウザパスの設定
パッケージ名は大文字小文字を区別しないので、pip install drissionpage でも同じものが入ります。依存としてlxml・requests・websocket-client・cssselectなどが一緒に入ります。
python -m venv .venv
# macOS・Linuxのbash/zsh
source .venv/bin/activate
# Windows PowerShellでは次を実行
# .venv\Scripts\Activate.ps1
pip install DrissionPage
python -c "import DrissionPage; print(DrissionPage.__version__)"
# 4.1.1.4
ブラウザは既定でシステム内のChromeを探します。見つからない場合や、EdgeなどChrome以外のChromium系ブラウザを使う場合は、付属のコマンド dp でパスを登録します。登録内容は設定ファイルに保存され、以後の起動で使われます。
dp -p "C:\Program Files\Google\Chrome\Application\chrome.exe"
パスは、ブラウザのアドレスバーに chrome://version(Edgeは edge://version)と入力すると「実行ファイルのパス」として表示されます。コマンドを実行するPython環境は、プロジェクトで使う仮想環境と同じにしておきます。
Chromium()の基本操作:ページ表示・入力・クリック
ローカル検証ページの作成とHTTPサーバーの起動
外部サイトを例にすると、相手のページが変わった時点でコードが動かなくなります。実際、以前は多くの解説が例に使っていたexample.comのページには、2026-10-24時点で h1 要素が無く、tab.ele('tag:h1').text は ElementNotFoundError で止まりました。この記事では、以降のコードをすべて次の検証用ページで動かします。空のフォルダに index.html を作ります。
<meta charset="utf-8"><title>DrissionPage検証</title>
<input name="q"><button id="go" onclick="load()">検索</button>
<ul id="list"></ul>
<a id="nt" href="page2.html" target="_blank">別タブで開く</a>
<a id="dl" href="data.csv">CSVをダウンロード</a>
<iframe id="f" src="frame.html"></iframe>
<script>
function load() {
fetch('api.json?q=' + document.querySelector('[name=q]').value)
.then(r => r.json())
.then(d => d.items.forEach(x => {
const li = document.createElement('li');
li.textContent = x;
document.getElementById('list').append(li);
}));
}
setTimeout(() => {
const p = document.createElement('p');
p.textContent = 'late text';
document.body.append(p);
}, 1500);
</script>
ボタンを押すと api.json を取りに行って一覧を描き、読み込みの1.5秒後には「late text」という段落が追加されます。残りの4ファイルを作り、同じフォルダでローカルサーバーを起動します(macOS・Linuxのシェルの例)。
echo '{"items": ["a", "b", "c"]}' > api.json
echo '<meta charset="utf-8"><p id="inner">iframeの中</p>' > frame.html
echo '<meta charset="utf-8"><title>2ページ目</title><p>2ページ目</p>' > page2.html
printf 'name,price\napple,100\n' > data.csv
python -m http.server 8000 --bind 127.0.0.1
ページを開いて入力・クリック・読み取りをする最小コード
4.1以降の推奨形では、Chromium オブジェクトがブラウザ本体を、そこから取り出すタブオブジェクトが個々のページを担当します。サーバーを起動したまま、別のターミナルで次を実行します。後続の要素検索・iframe・別タブ・スクリーンショット・ダウンロードの断片コードを試す場合は、この最小コードの末尾にある browser.quit() の直前へ、試したいコードを挿入してください。コメントは実際の出力で、4.1.1.4と5.0.0b1で同じでした。
from DrissionPage import Chromium, ChromiumOptions
co = ChromiumOptions().headless().auto_port()
browser = Chromium(co)
tab = browser.latest_tab # 4.1.1.4ではMixTab型、5.0.0b1ではChromiumTab型
tab.get('http://127.0.0.1:8000/index.html')
print(tab.title) # DrissionPage検証
tab.ele('@name=q').input('drission') # 入力欄に文字を入れる
tab.ele('#go').click() # ボタンを押す
tab.wait.ele_displayed('tag:li', timeout=5)
print([li.text for li in tab.eles('tag:li')]) # ['a', 'b', 'c']
print(tab.ele('#nt').attr('href')) # http://127.0.0.1:8000/page2.html
browser.quit()
ele() は1件、eles() は全件を返し、.text で文字列、.attr('属性名') で属性値を読みます。href は相対パスで書いていても絶対URLで返りました。クリックで一覧が描かれるまでには通信の時間がかかるため、tab.wait.ele_displayed() で表示を待ってから読み取ります。
ChromiumPageで書かれたコードの書き換え
公式ドキュメントの4.1の解説によると、ChromiumPage は「ブラウザと1つのタブが合体したオブジェクト」で、Selenium時代の設計の名残です。概念が分かりにくくタブ管理で混乱しやすいため、4.1で Chromium を入口に変え、既存プロジェクトのために ChromiumPage と WebPage は残されました。
公式の5.0解説ページで作者は、4.1から使わないよう呼びかけてきたのに検索で出るチュートリアルもAIの回答も ChromiumPage のままだと書き、削除を決めたと説明しています。5.0.0b1を入れると次のようになります。
>>> from DrissionPage import ChromiumPage
ImportError: cannot import name 'ChromiumPage' from 'DrissionPage'
>>> import DrissionPage; [x for x in dir(DrissionPage) if not x.startswith('_')]
['Chromium', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'errors', 'version']
書き換えは機械的です。page = ChromiumPage() を tab = Chromium().latest_tab に置き換え、以降の page.get() や page.ele() は tab に読み替えます。今から書くコードで ChromiumPage を選ぶ理由はありません。
既定の9222番ポートによる既存ブラウザの接管
オプションを何も指定しない Chromium() は、127.0.0.1の9222番ポートにつなぎます。公式ドキュメントのとおり、そのポートですでにブラウザが動いていれば新しく起動せずに接管(乗っ取り)します。前回の実行で閉じ忘れたブラウザや、別の用途でデバッグポートを開けていたブラウザを操作してしまう原因になります。
並列実行やCIでは ChromiumOptions().auto_port() を付けます。この指定で起動すると空きポート(ある回は56971番)が選ばれ、ユーザーデータも一時ディレクトリ配下の DrissionPage/autoPortData/56971 に分かれました。ログイン状態を持ち越したいときは逆に、固定ポートと次の節の固定プロファイルを使います。
プロキシとプロファイルの指定:4.1は認証付きプロキシ非対応
起動時の設定は ChromiumOptions にまとめて渡します。
co = (ChromiumOptions()
.set_proxy('http://127.0.0.1:3128') # 認証なしのHTTPプロキシ
.set_user_data_path('/path/to/dp-profile')) # ログイン状態を残すプロファイル
browser = Chromium(co)
注意したいのは、ユーザー名とパスワード付きのプロキシです。4.1.1.4で set_proxy('http://user:[email protected]:3128') と書くと「You seem to be setting up a proxy that uses the account password, which is not supported for the time being」と表示され、文字列はそのままChromeの --proxy-server に渡されます。ソースの警告文は、拡張機能で自前に実装するよう案内しています。5.0.0b1では同じ文字列を渡すと、接続先 http://127.0.0.1:3128 とユーザー名・パスワードを分けて保持しました。リポジトリのREADMEも、5.0から set_proxy() と new_context(proxy=...) が認証付きプロキシに直接対応すると書いています。認証付きプロキシが必須の業務は、4.1.1.4のままでは拡張機能を自作するか、5.0の正式版を待つことになります。
要素の探し方:ロケータ構文と見つからないときの挙動
ロケータ構文の書き分け
ロケータは文字列1つで書け、先頭の記号で探し方が変わります。一致のさせ方は = が完全一致、: が部分一致、^ が前方一致、$ が後方一致です。
| 書き方 | 意味 |
|---|---|
#go |
idがgo |
.item |
classがitem |
@name=q |
属性nameがq |
text=late text |
テキストが完全一致 |
tag:p@@text():late |
pかつテキストにlateを含む |
css:ul>li |
CSSセレクタ |
xpath://h1 |
XPath |
複数条件は @@ でつなぐとAND、@| でOR、@! で否定になります。ただし探す文字列自体に @@ などが含まれる場合は使えず、XPathに切り替えるよう公式の構文ページに書かれています。
記号なし・text:の部分一致がscriptタグを拾う問題
記号を付けずに tab.ele('late') と書くと、4.1.1.4ではテキストの部分一致になります。5.0.0b1では先にXPathやCSSセレクタとして照合し、一致しない場合にテキストの部分一致へ進みます。この部分一致は、画面に見えない <script> の中身も対象にします。
検証用ページで「late text」の段落が表示されたのを確かめてから探すと、4.1.1.4と5.0.0b1のどちらでも、tab.ele('late') と tab.ele('text:late') は段落ではなく script 要素を返しました。段落を差し込むスクリプトのソースに同じ文字列が含まれ、文書の順でそちらが先に見つかるためです。tag:p@@text():late のようにタグを添えるか、完全一致の text=late text にすると目的の p が取れました。
見つからないときのNoneElementと待ち時間
ele() は要素が現れるまで待ちます。既定の待ち時間は設定ファイルの base = 10 で10秒です。検証用ページで存在しない要素を探したときの挙動を測ると次のとおりでした。
- 既定では10.0秒待ったあと、例外ではなく
NoneElementを返す(真偽値はFalse) NoneElementの.textなどを読んだ時点でElementNotFoundErrorが発生するtimeout=1を渡すと1.03秒で戻る
el = tab.ele('#result', timeout=5)
if el:
print(el.text)
else:
print('見つからない')
見つからない時点で止めたいバッチ処理なら、from DrissionPage.common import Settings のあと Settings.set_raise_when_ele_not_found(True) を呼ぶと、ele() の呼び出し自体が ElementNotFoundError を送出します。何も書かないと、見つからないたびに10秒ずつ待ちながら処理が進むので、ループの中では待ち時間を明示しておきます。表示まで待ちたいときは、最小コードで使った tab.wait.ele_displayed() を使います。tab.wait.doc_loaded() が待つのは主文書の読み込み完了で、JavaScriptによる後続の表示更新は待ちません。
iframe・別タブ・スクリーンショット・ダウンロードの操作
iframe内の要素:別オリジンは4.1.1.4ならget_frame()を経由
Seleniumのようにiframeへ「切り替える」操作はありません。同じオリジンのiframeなら、タブから直接探せます。
print(tab.ele('#inner').text) # iframeの中
print(tab.get_frame('#f').ele('#inner').text) # iframeの中(iframeを明示する書き方)
結果が変わるのは別オリジンのiframeです。index.html のiframeの src を http://localhost:8000/frame.html に変えてオリジンをずらすと、4.1.1.4では tab.ele('#inner') が NoneElement になり、get_frame('#f') を経由したときだけ取れました。5.0.0b1ではタブから直接取れました。公式の5.0解説ページも、別オリジンiframe内の要素取得と通信の監視に5.0で対応したと書いています。4.1.1.4を使う間は、iframeの中は get_frame() で探すと決めておくと、オリジンの違いで動かなくなる事故を避けられます。
別タブで開いたページの操作
target="_blank" のリンクで開くタブは、click.for_new_tab() で受け取ります。クリック後に新しいタブが現れるまで待ってからそのタブを返すため、クリック直後に browser.latest_tab を読んで元のタブをつかむ取り違えが起きません。元の tab を操作し続けたまま、新しいタブを並行して扱えます。
new_tab = tab.ele('#nt').click.for_new_tab()
new_tab.wait.doc_loaded()
print(new_tab.title) # 2ページ目
print(len(browser.tab_ids)) # 2
new_tab.close()
タブの数は browser.tab_ids の長さで数えると両版で動きます。自分でタブを増やすときは browser.new_tab('URL') を使います。
ページ全体のスクリーンショットとファイルのダウンロード
print(tab.get_screenshot(path='shots', name='full.png', full_page=True))
# 絶対パスで .../shots/full.png
tab.set.download_path('downloads')
mission = tab.ele('#dl').click.to_download()
print(mission.wait(show=False)) # .../downloads/data.csv
full_page=True を付けると、画面外まで含めたページ全体を1枚に撮ります。高さ3,000px超のページで試すと、付けない場合は1280×713、付けた場合は1265×3419の画像になりました。click.to_download() はクリックで始まるダウンロードを待ち受け、wait() が保存先のパスを返します。同名のファイルがあると上書きせず、data_1.csv のように番号を付けて保存されました。毎回同じ名前で受け取る処理では、事前に古いファイルを消しておきます。
通信データの取得:listenによるXHR応答の直接受信
画面に表示されるデータの多くは、JavaScriptがAPIから取ってきたJSONです。DOMから文字を拾う代わりに、その通信の応答を直接受け取れるのがDrissionPageの強みです。検証用ページの検索ボタンが呼ぶ api.json を待ち受けます。
from DrissionPage import Chromium, ChromiumOptions
browser = Chromium(ChromiumOptions().headless().auto_port())
tab = browser.latest_tab
tab.listen.start('api.json') # URLにapi.jsonを含む通信を待ち受ける
tab.get('http://127.0.0.1:8000/index.html')
tab.ele('@name=q').input('drission')
tab.ele('#go').click()
packet = tab.listen.wait(timeout=5)
if not packet:
raise TimeoutError('対象の通信を5秒以内に取得できませんでした')
print(packet.url) # http://127.0.0.1:8000/api.json?q=drission
print(packet.response.body) # {'items': ['a', 'b', 'c']}
browser.quit()
出力はコメントのとおりで、4.1.1.4と5.0.0b1で同じ結果でした。5.0では listen.start() から method と res_type の引数が削除されますが、URLの文字列だけを渡すこの書き方は両方で動きます。
JSONオブジェクトの応答なら response.body は辞書になり、JSON配列ならリストで返ります。画面のレイアウトが変わってもAPIの形が同じなら取得処理は壊れないため、定期実行するスクリプトほどこの方法を優先する価値があります。listen.start() は get() より前に呼ばないと、ページ読み込み時の通信を取りこぼします。
SessionPageとモード切替:ブラウザを起動しない取得の使いどころ
SessionPageの取得範囲とJavaScript非実行の制約
SessionPage はrequestsでHTMLを取得し、ブラウザ版と同じロケータ構文で要素を探せるオブジェクトです。ブラウザの起動と描画の処理を省けますが、JavaScriptは実行されません。検証用ページを SessionPage で開くと、title やiframeのタグは取れましたが、JavaScriptで後から追加される「late text」の段落は NoneElement になりました。
もう1つ注意したいのが既定のUser-Agentです。受け取ったヘッダーを返すだけのローカルサーバーへ SessionPage で接続すると、4.1.1.4・5.0.0b1とも Version/10.1.2 Safari/603.3.8(macOS 10.12.6のSafari 10.1.2)を名乗り、accept-charset: GB2312,utf-8 を付けて送っていました。同梱の設定ファイルの既定値です。2017年ごろのブラウザを名乗るため、サイトによっては旧ブラウザ向けの表示に切り替わったり弾かれたりします。SessionPage(SessionOptions().set_headers({'user-agent': '...'})) のように明示しておくと挙動が安定します。
HTMLが静的で、取得したあとの解析が中心ならBeautifulSoupとrequestsの組み合わせでも足ります。書き方はBeautifulSoupとは?pip installと使い方(find・select)を解説【bs4 4.15】を参照してください。
change_mode()で引き継がれるもの・引き継がれないもの
4.1.1.4の MixTab と5.0.0b1の ChromiumTab は、ブラウザで操作するdモードとrequestsで取得するsモードを change_mode() で切り替えられます。ログインだけブラウザで済ませ、その後の大量取得を軽いsモードで回す使い方が典型です。
切り替え時に任意のヘッダー一式は同期されません。ただし4.1.1.4と5.0.0b1の既定のd→s切り替えでは、cookiesとともにブラウザのUser-Agentもコピーされます。検証でも、切り替え後のsモードは HeadlessChrome/155.0.0.0 を含むUser-Agentを使っていました。公式ドキュメントは、特定のヘッダーを要求するサイトではsモードでの取得が応答待ちのままタイムアウトまで止まると注意しています。また切り替えると同じURLを取り直すため、JavaScriptで描画された要素はsモード側には存在しません。検証用ページでも、dモードで見えていた「late text」の段落は、change_mode('s') のあとに探すと両版とも NoneElement でした。
5.0ベータで変わる点と移行の準備
5.0は2026-10-24時点でもベータ版(pip install DrissionPage --pre --upgrade で入る)で、公式ドキュメントのトップは「当前文档适用于:DrissionPage 4.1.1.4」と表示しています。公式の5.0解説ページが挙げる主な変更は次のとおりです。
ChromiumPageとWebPageを削除し、モード切替の機能をタブオブジェクトChromiumTabに統合- 内部ロジックを作り直し、メモリ使用量を削減
browser.new_context(proxy=...)でcookiesとプロキシが独立したブラウザコンテキストを作成(1つのブラウザで複数アカウントにログインできる)- DrissionPageが起動したブラウザ、または
--disable-site-isolation-trialsを付けて起動したブラウザでは、別オリジンiframe内の要素検索と通信監視をタブから直接行える(不具合が出たらChromiumOptions().close_cross_origin()で無効化)
この記事のコードを5.0.0b1で動かして差が出たのは、タブの型(MixTab → ChromiumTab)、get() の戻り値(True → URLとステータスを持つ NavResult)、別オリジンiframeの直接検索、認証付きプロキシの扱いの4点でした。Chromium を入口にしていても、get() の戻り値で成否を判定しているコードや、5.0で削除された browser.tabs_count を使うコードは書き換えが要ります。
業務のスクリプトをいまベータ版に上げる必要はありません。正式版で ChromiumPage が消えるのは作者が明言した方針なので、4.1.1.4のうちに入口を Chromium() へ直し、get() の戻り値に頼らない書き方にしておくと、5.0への移行で直す箇所が減ります。
Cloudflareなどのbot対策とDrissionPageの関係
「DrissionPageならCloudflareを回避できる」という紹介を見かけますが、実測するとbotとして見分けられる要素は残っています。WebDriverを使わないため、Seleniumで問題になる navigator.webdriver は false でした。一方でヘッドレスモードのUser-Agentは HeadlessChrome/155.0.0.0 となり、ヘッドレスブラウザであることをそのまま名乗っています。
Cloudflareのチャレンジやbot判定は、サイト運営者がアクセスを制限するために置いている仕組みです。それを回避して取得することは、前述のライセンスが禁じる「他人の利益を損なう」利用や、robots.txtに反する収集に当たりうるうえ、多くのサイトの利用規約にも反します。取得したいデータがあるなら、公開APIやデータ提供の有無を先に確認し、無ければ運営者の許可を得るのが順序です。
正規に許可を得た自社サイトの監視やテストで、チャレンジ画面がテストの邪魔になる場合は、CloudflareのSecurity Eventsで判定元を確認し、対象機能に対応する方法でテスト用送信元の例外を設定します。Super Bot Fight ModeではSkipルールを使えますが、Bot Fight Modeには同じ方法を適用できません。
Selenium・Playwrightとの選び分け
| 項目 | DrissionPage | Selenium | Playwright |
|---|---|---|---|
| ライセンス | 独自(商用は要許可) | Apache-2.0 | Apache-2.0 |
| 対応ブラウザ | Chromium系のみ | Chrome・Edge・Firefox・Safari | Chromium・Firefox・WebKit |
| 接続方式 | CDP直結 | WebDriver | CDPほか独自プロトコル |
| 言語 | Pythonのみ | Java・Python・C#など | TS/JS・Python・Java・.NET |
| HTTP取得との切替 | 標準で持つ | 無い | APIRequestContextで可 |
| ドキュメント言語 | 中国語が中心 | 英語ほか | 英語ほか |
判断の分かれ目はライセンスと対象ブラウザです。商用の業務で許諾を取る予定が無いなら、DrissionPageは候補から外れます。複数ブラウザでの表示確認やE2Eテストが目的ならPlaywrightかSeleniumで、テストランナーやトレース機能まで揃っているPlaywrightが第一候補です。Safariそのものの確認が要るならSeleniumのsafaridriverを使います。PlaywrightのWebKitはSafari本体ではありません。
DrissionPageが向くのは、個人の学習や非営利の調査で、Pythonだけで「ログインはブラウザ、大量取得はHTTP」という混在した処理を短く書きたい場面です。通信の応答を受け取る機能はPlaywrightにも expect_response() があるため、既存コードとの統合やテスト機能まで含めて選びます。業務システムにブラウザ操作の自動化を組み込む場合は、ライセンスの確認を含めて設計段階から決めておく必要があり、フルスクラッチ開発として要件から相談いただくこともできます。
各ツールの詳細はSeleniumとは?使い方をPythonで解説|4.51対応・ChromeDriverの手動設定が要らない書き方とPlaywright(プレイライト)とは?仕組み・できること・Seleniumとの違いを解説、AIエージェントやRPAまで含めた方式の比較はBrowser Automationとは?ブラウザ操作を自動化する4つの方式と選び方【2026年】で扱っています。
よくある質問
DrissionPageの公式ドキュメントはどこにありますか?
公式サイトはdrissionpage.cnで、2026-10-24時点の表示は「当前文档适用于:DrissionPage 4.1.1.4」です。本文は中国語で、ソースはGitHubのg1879/DrissionPageのほか、GiteeとGitCodeにもあります。4.2と5.0の変更点は公式サイトの「新版本介绍」にまとまっています。
from DrissionPage import ChromiumPageはまだ使えますか?
安定版の4.1.1.4では使えますが、5.0.0b1ではImportErrorになります。from DrissionPage import Chromium と Chromium().latest_tab に書き換えておけば、どちらの版でも動きます。
DrissionPageでCloudflareは回避できますか?
回避を目的に使うことは勧めません。ヘッドレス時のUser-Agentは「HeadlessChrome」を含み、判別できる状態です。加えてライセンスは他人の利益を損なう利用とrobots.txtに反する収集を禁じており、違反すると許諾が失効します。
DrissionPageは会社の業務で使えますか?
権利者の許可なく商用に使うことはライセンスで禁じられています。業務で使う場合は作者から許諾を得てください。許諾を取らないなら、Apache-2.0のSeleniumかPlaywrightを選びます。
DrissionPageをMCPサーバーとしてAIエージェントから使えますか?
作者の公式品ではありませんが、第三者が公開する drissionpage-mcp があります。PyPIのページでは2026-10-24時点の最新が0.8.8(2026-09-09公開)、ライセンスはApache-2.0で、依存は DrissionPage>=4.1.1.4,<5 です。MCPサーバー側がApache-2.0でも、内部で動くDrissionPage本体には前述の独自ライセンスがそのまま掛かるため、業務での利用条件は変わりません。