仕事でweb情報を収集する必要があり、ローカルPCでスクレイピングを行っていましたが、自分のpcのメモリを占有してしまい重くなってしまいました。
そこでクラウドサーバーやVPSを利用しようと考えましたが、そういった多人数が使えるサーバーは大半のwebサイトではクローラーブロックされておりクローラーがアクセスできません。
ですので納得できる構成要素を考えてみました。
まずWebスクレイピングの構成要素として、自前のサーバー内で処理を行う、スクレイピングツールを利用するなど、クラウドサーバーを利用するなど様々な方法が浮かぶかと思います。
しかし、スクレピングツールは自由度が少なく要件を満たせないことや、自前サーバーを利用するとクローラーブロックされる危険性があります。
そういう問題に直面している人は、この記事に記載する方法のLambda + headless構成を試してみてはいかがでしょうか?
必要モジュールのインストール
Lambda で外部モジュールを使用するためには、レイヤー作成しそこから読み込みを行います。
そのためそれ用にまず zip フォルダを作成し Lambda にアップロードします。
今回は二つのフォルダを作成します。
python フォルダを作成し以下モジュールを保存します。
保存方法 pip を使用するか、サイトから直接ダウンロードするかお好みで行います
boto3
boto3-1.16.23.dist-info
numpy
numpy-1.19.2.dist-info
pandas
pandas-1.1.3.dist-info
pytz
pytz-2020.1.dist-info
requests
requests-2.24.0.dist-info
selenium
selenium-3.141.0.dist-info
urllib3
urllib3-1.26.2.dist-info
同様に headless フォルダを作成、以下ファイルを保存します。
保存方法は wget や curl、サイトから直接ダウンロードするかどちらかお好みで行います
構成としては以下のようになります
headless
– python
– bin
– chromedriver
– headless-chromium
レイヤーの作成
これらのフォルダを zip 圧縮し、レイヤーを作成します。
この時、レイヤー名はフォルダ名と同値にし、互換性のあるランタイムを python3.7 にします
バケットの作成
s3 に移動し、バケットを作成します。
名前はお好みで作成します。
Lmabda コードの作成
ラムダを作成し、2 で作ったレイヤーを登録します。
この時 python のバージョンは 3.7 を選択してください。
コード内の[作成したバケット名を記載してください]は3で作成しバケット名と同値にしてください。
コードを以下に記します
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
import boto3
import time
s3 = boto3.resource(‘s3’)
import os
def Lambda_handler(event, context):
chrome=Chrome()
browser=chrome.headless_Lambda()
browser.get(‘https://dev.to/’)
title = browser.title
time.sleep(5)
image_url = “/tmp/”+title + “.png”
sfile = browser.get_screenshot_as_file(image_url)
browser.close()
browser.quit()
bucket = ‘作成したバケット名を記載してください’
s3.meta.client.upload_file(image_url, bucket, title + “.png”)
obj = s3.Object(bucket, title)
return { “flg”: sfile }
class Chrome:
def headless_Lambda(self):
options = webdriver.ChromeOptions()
options.binary_location = “/opt/headless/python/bin/headless-chromium”
options.add_argument(“–headless”)
options.add_argument(“–no-sandbox”)
options.add_argument(“–single-process”)
options.add_argument(“–disable-gpu”)
options.add_argument(“–window-size=1280×1696”)
options.add_argument(“–disable-application-cache”)
options.add_argument(“–disable-infobars”)
options.add_argument(“–hide-scrollbars”)
options.add_argument(“–enable-logging”)
options.add_argument(“–log-level=0”)
options.add_argument(“–ignore-certificate-errors”)
options.add_argument(“–homedir=/tmp”)
driver = webdriver.Chrome(
executable_path=”/opt/headless/python/bin/chromedriver”,
chrome_options=options
)
return driver
Lambda 権限の設定
最後に権限を編集します。
今のままでは Lambda には s3 にアクセスする権限がありません
そのため Lambda のアクセス権限から実行ルールを編集し、【AmazonS3FullAccess】
権限を追加します。
最後に
テストを実行し、スクリーンショットが s3 に保存されていることを確認します。
これで問題なくクラウドを利用した、スクレイピングが行えることを確認できたかと思います。
今回はs3にスクショ保存機能を実装しましたが、構成さえ考えてしまえば、様々スクレイピング機能を実装できるかと思います。
後は好きなように作り替えてみましょう!