Add your description here
Project description
quickplay
Overview - 概要
quickplay is a scraping utility library built on Patchright and selectolax. quickplayはPatchrightとselectolaxをベースにしたスクレイピングユーティリティライブラリです。
- PlayPage — Patchright
Pageのラッパー。スクレイピング用。 - SelectParser — selectolax
HTMLParserのラッパー。ローカル抽出用。 - browse_patchright() — Patchright(Chrome)起動ランナー。
- browse_camoufox() — Camoufox(Firefox)起動ランナー。bot検知対策向け。
- その他ユーティリティ — FromHere, sleep_between, append_csv, write_parquet, hash_name, save_html
Requirements - 必要条件
- Python 3.12 or higher
- Libraries: playwright, selectolax, pandas, camoufox(自動インストール)
write_parquetを使う場合は pandas の Parquet エンジンとしてpyarrow(またはfastparquet)が必要です。- Browser binaries(別途インストールが必要)
Installation - インストール
pip
pip install quickplay
uv (推奨)
uv add quickplay
ブラウザバイナリを別途インストールしてください。
Patchright(Chromium)
pip
python -m patchright install chromium
uv (推奨)
uv run patchright install chromium
Camoufox(Firefox)
pip
camoufox fetch
uv (推奨)
uv run camoufox fetch
Quick Reference - 主要メソッド一覧
PlayPage のメソッド
-
ss(selector: str) -> list[ElementHandle]
指定したCSSセレクタにマッチするすべての要素をリストで返します。
例:links = p.ss('a') -
s(selector: str) -> ElementHandle | None
指定したCSSセレクタにマッチする最初の要素を返します。見つからなければNone。
例:title_elem = p.s('h1') -
text(elem: ElementHandle | None) -> str | None
要素からテキスト内容を取得します(前後の空白は除去されます)。
例:title = p.text(p.s('h1')) -
attr(attr_name: str, elem: ElementHandle | None) -> str | None
要素の指定された属性値を取得します。
例:href = p.attr('href', link_elem) -
url(elem: ElementHandle | None) -> str | None
リンク要素 (<a>) のhrefを絶対URLに正規化して返します。無効なリンク(javascript:など)は除外されます。
例:next_url = p.url(p.s('a.next')) -
goto(url: str | None) -> bool
指定したURLに移動します。成功すればTrue、失敗すればFalseを返します。
例:if p.goto('https://example.com'): ...
SelectParser のメソッド
-
nxt(self, selector: str, node: LexborNode | None) -> LexborNode | None
ノードから、セレクタに一致する最初の弟ノードを取得します。 -
txt(self, node: LexborNode | None) -> str | None
ノードからテキスト内容を(子孫ノードまで全て含め)取得します(前後の空白は除去されます)。
ユーティリティ関数
-
sleep_between(a: float, b: float) -> None
a〜b秒の間でランダムに待機します。サーバーに負荷をかけないための基本的なマナーです。
例:sleep_between(1, 2) -
append_csv(path: Path | str, row: dict) -> None
dict形式のデータを1行としてCSVファイルに追記します。ファイルが存在しない場合はヘッダーも自動で書き込みます。
例:append_csv('data.csv', {'name': '太郎', 'age': 20}) -
write_parquet(path: Path | str, rows: list[dict]) -> None
dictのリストを1つの Parquet ファイルに書き出します。
例:write_parquet('data.parquet', [{'name': '太郎', 'age': 20}]) -
browse_patchright(fn: Callable[[Page], None], ...) -> None
Patchrightのブラウザを起動し、引数で渡した関数を実行します。 例:browse_patchright(scrape, user_data_dir='C:\Users\あなたのユーザ名\AppData\Local\Google\Chrome\User Data')
引数:def browse_patchright( # scrape(page) のような関数を渡す。 fn: Callable[[Page], None], # 'C:\Users\あなたのユーザ名\AppData\Local\Google\Chrome\User Data'のような文字列。 # chrome://version/で確認できる。 user_data_dir: str | Path, ) -> None:
-
browse_camoufox(fn: Callable[[Page], None], ...) -> None
Camoufox(Firefox)でブラウザを起動し、引数で渡した関数を実行します。bot検知が厳しいサイト向け。
例:browse_camoufox(scrape)
引数:def browse_camoufox( # scrape(page) のような関数を渡す。 fn: Callable[[Page], None], # ブラウザのロケール(言語・地域設定)を指定 # 英語サイト中心なら `'en-US,en'` への変更を検討 locale: str | list[str] | None = 'ja-JP,ja', ) -> None:
Basic Usage - 基本的な使い方
from quickplay import *
fh = FromHere(__file__)
add_log_file(fh('log/scraping.log'))
def scrape(page):
p = PlayPage(page)
p.goto('https://www.foobarbaz1.jp')
pref_urls = [p.url(e) for e in p.ss('li.item > ul > li > a')]
classroom_urls = []
for i, url in enumerate(pref_urls, 1):
print(f'{i}/{len(pref_urls)} pref_urls')
if not p.goto(url):
continue
sleep_between(1, 2)
links = [p.url(e) for e in p.ss('.school-area h4 a')]
classroom_urls.extend(links)
for i, url in enumerate(classroom_urls, 1):
print(f'{i}/{len(classroom_urls)} classroom_urls')
if not p.goto(url):
continue
sleep_between(1, 2)
append_csv(fh('csv/out.csv'), {
'URL': page.url,
'教室名': p.text(p.s('h1 .text01')),
'住所': p.text(p.s('.item .mapText')),
'電話番号': p.text(p.s('.item .phoneNumber')),
'HP': p.url(p.s_in('a', p.next(p.s_re('th', 'ホームページ')))),
})
if __name__ == '__main__':
browse_patchright(
scrape,
user_data_dir='C:\Users\あなたのユーザ名\AppData\Local\Google\Chrome\User Data',
)
Save HTML while scraping - スクレイピングしながらHTMLを保存する
from quickplay import *
fh = FromHere(__file__)
add_log_file(fh('log/scraping.log'))
def scrape(page):
ctx = {}
p = PlayPage(page)
p.goto('https://www.foobarbaz1.jp')
ctx['アイテムURLs'] = [p.url(e) for e in p.ss('ul.items > li > a')]
for i, url in enumerate(ctx['アイテムURLs'], 1):
print(f'{i}/{len(ctx['アイテムURLs'])} アイテムURLs')
if not p.goto(url):
continue
sleep_between(1, 2)
if not p.wait('#logo', timeout=10000):
continue
file_name = f'{hash_name(url)}.html'
if not save_html(fh('html') / file_name, page.content()):
continue
append_csv(fh('outurlhtml.csv'), {
'URL': url,
'HTML': file_name,
})
if __name__ == '__main__':
browse_patchright(
scrape,
user_data_dir='C:\Users\あなたのユーザ名\AppData\Local\Google\Chrome\User Data',
)
Scrape from local HTML files - 保存済みHTMLからスクレイピングしてParquetに出力する
import pandas as pd
from quickplay import *
fh = FromHere(__file__)
add_log_file(fh('log/scraping.log'))
p = SelectParser()
df = pd.read_csv(fh('outurlhtml.csv'))
results = []
for i, (url, path) in enumerate(zip(df['URL'], df['HTML']), 1):
print(i)
if not p.load(fh('html') / path):
continue
results.append({
'URL': url,
'教室名': p.txt(p.s('h1 .text02')),
'住所': p.txt(p.s('.item .mapText')),
'所在地': p.txt(p.nxt('dd', p.s_re('dt', r'所在地'))),
})
write_parquet(fh('outhtml.parquet'), results)
License - ライセンス
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quickplay-1.2.10.tar.gz.
File metadata
- Download URL: quickplay-1.2.10.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.33.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0479f87e66f65a6c65d4c0cc5bc5ce8ef34e1c79d5ca278339bf4b8c48a048a1
|
|
| MD5 |
fcd20fd53ded87d28ebf1746f12546b5
|
|
| BLAKE2b-256 |
25694acdb864538d9c1ac2c1e635c9c0631364b3e28c39dc0f475c6f20bb0687
|
File details
Details for the file quickplay-1.2.10-py3-none-any.whl.
File metadata
- Download URL: quickplay-1.2.10-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.33.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
688b06237e433aa3d0115bc9665a47c0a39557a19063b24691f50070074676e3
|
|
| MD5 |
131fa4de536780881f0d08335bce580c
|
|
| BLAKE2b-256 |
0c62f4ebc52c52843893f9e127475f2ee4c3cc095e7c7bfd979454a0daf525d6
|