目次
- 諸言
- なぜ好きなのか
- クローラの辛みに効くScrapy+Playwright
- 結言
諸言
初めまして!株式会社 Panta RheiのCEOです。かずさんと呼ばれているので以後そんな感じでお呼びください。Xのハンネはpandasista(@sotsogprinciple)です。
好きなクローラを発表します。
scrapy + Playwright です。
好き好き大好き。
なぜ好きなのか
Scrapyが良い
- ORM(SQLAlchemy)を標準装備しており簡単DB接続
- データフローを構築しやすくパブリッククラウドと相性が良い
- データ取得を自動化しやすい
- 多種類のWebサイトをクロールを統一の設定で実行できる
- CookieやCacheなどの多種類の設定をTrueFalseのみで設定
- Middlewareとして多くの途中処理を追加できる
- データを綺麗にする関数(例: 予想外のHTMLタグの削除)などをデータ取得時なのか、DB格納時なのか、何かの処理を行った後なのか、などデータの処理が柔軟かつ簡単
- 高速軽量!
- 【高速】 SeleniumやPuppeterなどのクローリングパッケージは(ヘッドレス)ブラウザの利用を前提にしているが、Scrapyはそれがないためブラウザ起因の遅延なし
- 【軽量】 JSを読まないため, SEO関連やSNS関連のscriptタグを無視。プレーンなHTMLテキストのみが対象なので、画像等のデータを読み込まず!
Playwrightが良い
- JSを解釈!
- JSによる動的なコンテンツを解釈できる
- Puppeterより良い
scrapy-playwrightが良い
JavaScriptがゴリゴリなページをクロールしようとすると、Scrapyではデータが取得できないです。「このページだけJavaScriptをexcuteして動的なコンテンツを取得したいなぁ」なんてとき、Playwrightを導入します。ScrapyとPlaywrightの繋ぎこみにはscrapy-playwright
です。
scrapyのspiderでは以下のように実装します。
from playwright.async_api import async_playwright
class Spider(scrapy.Spider):
name = "test"
start_urls = [
"https://test.test"
]
def start_request(self, response):
for start_url in start_urls:
yield scrapy.Request(
url=start_url,
callback=self.parse,
meta={
"playwright": True,
"playwright_include_page": True}
)
def parse(self, response):
page = response.meta["playwright_page"]
hoge_url = await page.locator("//div[@class='hogeclass']/a/@href").all()
item["hogeurl"] = hoge_url
yield item
JSを動かしたいページにscrapy.Requestする際に、meta
という引数を渡してあげるます。
すると読み込んだページがJSを解釈できるようになります。
それSeleniumでも良くない?
Seleniumはご存知の通り、E2Eテストやクローラにかなり用いられるパッケージです。が、現在ScrapyのアドオンとしてSeleniumを使うのはベスプラとは言いにくい状態です。
Scrapy上でSeleniumを用いるためのモジュールであるscrapy-selenium
の開発リリースが2019年で止まっています。Scrapyは2020年に大きなアップデート(1系から2系)があり、scrapy-seleniumを使い続けるとそのアップデートの良さみを享受できないことになります。
まとめ
ScrapyはPlaywrightと合わせるとDB接続が容易で高速でJS解釈できるスーパークローラになるよ!
結言
株式会社Panta Rheiはデータを用いて、さまざまな事業を展開しています。
- Google Cloudを用いたモダンなデータ収集基盤の構築
- 内製化AIの実装運用
- 企業データベースのAPI連携
などさまざまなソリューションを持っています。
何かお困りごと等ありましたら、ぜひご一報いただければと思います!