GoogleCloudFunctions에서 Selenium 사용

소개



GoogleCloudFunctions에서 Selenium을 사용해야하며 여기을 참조했습니다.
단지 GoogleCloudFunctions의 사양이 바뀌어 버렸는지, 한 번 수고 필요했기 때문에 기사에 정리해 보았습니다.

headlessChrome 준비



chromedriver 및 headless-chromium을 가져옵니다.

htps : // 기주 b. 코 m / ry 후우 s / gcf - packs
여기를 다운로드하고 압축을 풉니 다.

아래 이미지와 같이 selenim_chrome 폴더 → source 폴더에 파일이 있습니다.
※headless-chromium은 source 폴더에 있는 headless-chromium.zip을 압축해제합니다.


GoogleCloudFunctions에 배포할 폴더 준비



chromedriver, headless-chromium, main.py, requirements.txt를 폴더에 넣습니다.
※python 이외의 언어를 사용하는 경우, 적절히 변경해 주세요.


GoogleCloudFunctions에서 Selenium 사용



chromedriver와 headless-chromium을 다른 폴더에 복사



이번 제일의 포인트입니다.
GoogleCloudFunctions에 배포하면 chromedriver와 같은 파일이 현재 디렉토리 "/user_code"에 있습니다. 그러나 이 하위 파일에는 액세스할 수 없습니다. 대신 "/tmp"폴더라면 사용자가 자유롭게 액세스할 수 있습니다.

즉, chromedriver · headless-chromium을 "/tmp"폴더에 복사해야합니다.
또한 파일 권한을 변경합니다. 파일 권한의 변경에 대해서는 여기 를 참고로 했습니다.

파일 권한을 변경하는 함수
def add_execute_permission(path: Path, target: str = "u"):
    """Add `x` (`execute`) permission to specified targets."""
    mode_map = {
        "u": stat.S_IXUSR,
        "g": stat.S_IXGRP,
        "o": stat.S_IXOTH,
        "a": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH,
    }

    mode = path.stat().st_mode
    for t in target:
        mode |= mode_map[t]

    path.chmod(mode)

현재 디렉토리에서 "/tmp"로 복사 및 권한 변경
    driverPath = "/tmp" + "/chromedriver"
    headlessPath = "/tmp" + "/headless-chromium"

    # copy and change permission
    print("copy headless-chromium")
    shutil.copyfile(os.getcwd() + "/headless-chromium", headlessPath)
    add_execute_permission(Path(headlessPath), "ug")

    print("copy chromedriver")
    shutil.copyfile(os.getcwd() + "/chromedriver", driverPath)
    add_execute_permission(Path(driverPath), "ug")

Chrome 옵션



htps : // 기주 b. 코 m / ry 후우 s / gcf - packs
여기 main.py를 참고로 설정했지만 "user-agent=" + UserAgent().random"는 필요하지 않은 것 같습니다. 또한 disable-dev-shm-usage를 설정합니다.
※별로 자세히 조사하고 있지 않습니다・・・

프로그램 소스 및 설정 파일



위 내용을 근거로 한 프로그램 소스입니다.

※(2022/1/30 갱신) hideman씨보다 샘플 코드가 움직이지 않아! 라고 지적해 주셨습니다.
이전과 설정이 바뀌어 버린 것 같습니다…수정판으로 바꿨습니다. hideman 씨 감사합니다!

main.py
import os
import shutil
import stat
from pathlib import Path

from selenium import webdriver

global driver


def add_execute_permission(path: Path, target: str = "u"):
    """Add `x` (`execute`) permission to specified targets."""
    mode_map = {
        "u": stat.S_IXUSR,
        "g": stat.S_IXGRP,
        "o": stat.S_IXOTH,
        "a": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH,
    }

    mode = path.stat().st_mode
    for t in target:
        mode |= mode_map[t]

    path.chmod(mode)


def settingDriver():
    print("driver setting")
    global driver

    driverPath = "/tmp" + "/chromedriver"
    headlessPath = "/tmp" + "/headless-chromium"

    # copy and change permission
    print("copy headless-chromium")
    shutil.copyfile(os.getcwd() + "/headless-chromium", headlessPath)
    add_execute_permission(Path(headlessPath), "ug")

    print("copy chromedriver")
    shutil.copyfile(os.getcwd() + "/chromedriver", driverPath)
    add_execute_permission(Path(driverPath), "ug")

    chrome_options = webdriver.ChromeOptions()

    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--window-size=1280x1696")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--hide-scrollbars")
    chrome_options.add_argument("--enable-logging")
    chrome_options.add_argument("--log-level=0")
    chrome_options.add_argument("--v=99")
    chrome_options.add_argument("--single-process")
    chrome_options.add_argument("--ignore-certificate-errors")
    chrome_options.add_argument("--disable-dev-shm-usage")

    chrome_options.binary_location = headlessPath

    print("get driver")
    driver = webdriver.Chrome(executable_path=driverPath, options=chrome_options)


def seleniumSample(request):

    settingDriver()

    global driver
    try:
        print("URL get")
        driver.get("http://[hoge]")
        targetPath = '[HOGE]'
        ret = driver.find_element_by_xpath(targetPath)
        ret = ret.get_attribute("alt")
        print(ret)

    finally:
        print("driver quit")
        driver.quit()

    return ret

또한 배포 중에 설치할 패키지를 requirements.txt에 나열합니다.

requirements.txt
google-cloud-error-reporting==0.30.0
selenium
setuptools

요약



사용자가 만지는 폴더에 headlessChrome 등을 복사하여 Selenium을 실행할 수있었습니다.
약간의 스크래핑이라면 CloudFunctions에서 실행하는 것도 하나의 수단이 될까 생각합니다.

뭔가 도움이되면 다행입니다. 그럼.

참고



Google Cloud Functions에서 Python+selenium으로 스크래핑해 보세요.
[GoogleCloudFunctions(GCF) Python] GCF의 OS 및 동작에 대한 메모
파이썬 팁 : 파이썬에서 파일에 권한을 추가하고 싶습니다.

좋은 웹페이지 즐겨찾기