Hãy để tôi bắt đầu bằng cách bày tỏ sự thất vọng của mình 😡😡😡 với thực tế là AWS không có hình ảnh selen được định cấu hình sẵn cho Lambda trên thị trường ECR công khai của họ. Selenium là công cụ cần thiết để thử nghiệm giao diện người dùng và để xây dựng nhiều loại bot nhưng việc chạy nó trên Lambda rất phức tạp
Phương pháp đơn giản nhất là sử dụng SAM CLI cho Docker cho Lambda để tạo một hình ảnh với Selenium, Chrome/Chromium headless và webdriver, nhưng do cách Lambda hạn chế môi trường khiến nó hoạt động trên Selenium khá khó nhưng không phải là không thể
Trong hướng dẫn này, tôi sẽ cung cấp hướng dẫn về cách thực hiện chính xác điều đó
điều kiện tiên quyết
Thực hiện theo các hướng dẫn này để thiết lập môi trường phát triển của bạn
Nó sẽ hướng dẫn bạn cài đặt và cấu hình AWS CLI & SAM CLI
Tạo ứng dụng
Thực hiện theo các hướng dẫn trong
Cấu trúc thư mục của bạn sẽ giống như bên dưới
.
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── Dockerfile
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── template.yaml
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_handler.py
Tùy chỉnh ứng dụng
Đầu tiên, đổi tên thư mục
acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
4 thành acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
5trong đó. py
Cả hai tệp
acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
6 phải trốngSự kiện. sự kiện/sự kiện. json
Giữ nguyên nội dung của tệp
acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
7Ứng dụng. src/ứng dụng. py
Chúng tôi viết một chương trình Python đơn giản sử dụng Selenium webdriver để cạo một trang web
Thay đổi nội dung của tệp thành bên dưới
## Run selenium and chrome driver to scrape data from cloudbytes.dev
import time
import json
import os.path
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
def handler[event=None, context=None]:
chrome_options = webdriver.ChromeOptions[]
chrome_options.binary_location = "/opt/chrome/chrome"
chrome_options.add_argument["--headless"]
chrome_options.add_argument["--no-sandbox"]
chrome_options.add_argument["--disable-dev-shm-usage"]
chrome_options.add_argument["--disable-gpu"]
chrome_options.add_argument["--disable-dev-tools"]
chrome_options.add_argument["--no-zygote"]
chrome_options.add_argument["--single-process"]
chrome_options.add_argument["window-size=2560x1440"]
chrome_options.add_argument["--user-data-dir=/tmp/chrome-user-data"]
chrome_options.add_argument["--remote-debugging-port=9222"]
#chrome_options.add_argument["--data-path=/tmp/chrome-user-data"]
#chrome_options.add_argument["--disk-cache-dir=/tmp/chrome-user-data"]
chrome = webdriver.Chrome["/opt/chromedriver", options=chrome_options]
chrome.get["//cloudbytes.dev/"]
description = chrome.find_element[By.NAME, "description"].get_attribute["content"]
print[description]
return {
"statusCode": 200,
"body": json.dumps[
{
"message": description,
}
],
}
Phụ thuộc Python. src/yêu cầu. txt
Ghi lại các phụ thuộc của ứng dụng trong
acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
8selenium
requests
pandas
Phụ thuộc Chrome. src/chrome-deps. txt
Tạo một tệp có tên
acl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
9 với nội dung sauacl adwaita-cursor-theme adwaita-icon-theme alsa-lib at-spi2-atk at-spi2-core
atk avahi-libs cairo cairo-gobject colord-libs cryptsetup-libs cups-libs dbus
dbus-libs dconf desktop-file-utils device-mapper device-mapper-libs elfutils-default-yama-scope
elfutils-libs emacs-filesystem fribidi gdk-pixbuf2 glib-networking gnutls graphite2
gsettings-desktop-schemas gtk-update-icon-cache gtk3 harfbuzz hicolor-icon-theme hwdata jasper-libs
jbigkit-libs json-glib kmod kmod-libs lcms2 libX11 libX11-common libXau libXcomposite libXcursor
libXdamage libXext libXfixes libXft libXi libXinerama libXrandr libXrender libXtst libXxf86vm libdrm
libepoxy liberation-fonts liberation-fonts-common liberation-mono-fonts liberation-narrow-fonts
liberation-sans-fonts liberation-serif-fonts libfdisk libglvnd libglvnd-egl libglvnd-glx libgusb
libidn libjpeg-turbo libmodman libpciaccess libproxy libsemanage libsmartcols libsoup libthai libtiff
libusbx libutempter libwayland-client libwayland-cursor libwayland-egl libwayland-server libxcb
libxkbcommon libxshmfence lz4 mesa-libEGL mesa-libGL mesa-libgbm mesa-libglapi nettle pango pixman
qrencode-libs rest shadow-utils systemd systemd-libs trousers ustr util-linux vulkan
vulkan-filesystem wget which xdg-utils xkeyboard-config
Dockerfile. src/Dockerfile
Thay đổi nội dung của tệp thành bên dưới
FROM public.ecr.aws/lambda/python:3.9 as stage
# Hack to install chromium dependencies
RUN yum install -y -q sudo unzip
# Find the version of latest stable build of chromium from below
# //omahaproxy.appspot.com/
# Then follow the instructions here in below URL
# to download old builds of Chrome/Chromium that are stable
# Current stable version of Chromium
ENV CHROMIUM_VERSION=1002910
# Install Chromium
COPY install-browser.sh /tmp/
RUN /usr/bin/bash /tmp/install-browser.sh
FROM public.ecr.aws/lambda/python:3.9 as base
COPY chrome-deps.txt /tmp/
RUN yum install -y $[cat /tmp/chrome-deps.txt]
# Install Python dependencies for function
COPY requirements.txt /tmp/
RUN python3 -m pip install --upgrade pip -q
RUN python3 -m pip install -r /tmp/requirements.txt -q
COPY --from=stage /opt/chrome /opt/chrome
COPY --from=stage /opt/chromedriver /opt/chromedriver
COPY app.py ${LAMBDA_TASK_ROOT}
CMD [ "app.handler" ]
Script để cài đặt trình duyệt. src/cài đặt trình duyệt. sh
Tạo một tệp tại
FROM public.ecr.aws/lambda/python:3.9 as stage
# Hack to install chromium dependencies
RUN yum install -y -q sudo unzip
# Find the version of latest stable build of chromium from below
# //omahaproxy.appspot.com/
# Then follow the instructions here in below URL
# to download old builds of Chrome/Chromium that are stable
# Current stable version of Chromium
ENV CHROMIUM_VERSION=1002910
# Install Chromium
COPY install-browser.sh /tmp/
RUN /usr/bin/bash /tmp/install-browser.sh
FROM public.ecr.aws/lambda/python:3.9 as base
COPY chrome-deps.txt /tmp/
RUN yum install -y $[cat /tmp/chrome-deps.txt]
# Install Python dependencies for function
COPY requirements.txt /tmp/
RUN python3 -m pip install --upgrade pip -q
RUN python3 -m pip install -r /tmp/requirements.txt -q
COPY --from=stage /opt/chrome /opt/chrome
COPY --from=stage /opt/chromedriver /opt/chromedriver
COPY app.py ${LAMBDA_TASK_ROOT}
CMD [ "app.handler" ]
0. Chúng tôi sẽ sử dụng tập lệnh shell đơn giản để cài đặt trình duyệt web Chrome và Chrome mới nhất#!/bin/bash
echo "Downloading Chromium..."
curl "//www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/\
Linux_x64%2F$CHROMIUM_VERSION%2Fchrome-linux.zip?generation=1652397748160413&alt=media" > /tmp/chromium.zip
unzip /tmp/chromium.zip -d /tmp/
mv /tmp/chrome-linux/ /opt/chrome
curl "//www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/\
Linux_x64%2F$CHROMIUM_VERSION%2Fchromedriver_linux64.zip?generation=1652397753719852&alt=media" > /tmp/chromedriver_linux64.zip
unzip /tmp/chromedriver_linux64.zip -d /tmp/
mv /tmp/chromedriver_linux64/chromedriver /opt/chromedriver
Sau đó chạy lệnh dưới đây để làm cho tập lệnh có thể thực thi được
chmod +x src/install-browser.sh
mẫu. khoai mỡ
Thay đổi nội dung bên dưới. Dựa trên mức độ phức tạp của ứng dụng, bạn có thể cần tăng giá trị bộ nhớ và thời gian chờ trong Globals. Hàm số
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
python3.9
Sample SAM Template for selenium
# More info about Globals: //github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 120
MemorySize: 2048
Resources:
SeleniumFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures:
- x86_64
Events:
Selenium:
Type: Api
Properties:
Path: /selenium
Method: get
Metadata:
Dockerfile: Dockerfile
DockerContext: ./src
DockerTag: python3.9-v1
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# //github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
SeleniumApi:
Description: "API Gateway endpoint URL for Prod stage for Seleniumc function"
Value: !Sub "//${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/selenium/"
SeleniumFunction:
Description: "Selenium Lambda Function ARN"
Value: !GetAtt SeleniumFunction.Arn
SeleniumFunctionIamRole:
Description: "Implicit IAM Role created for Selenium function"
Value: !GetAtt SeleniumFunctionRole.Arn
Xây dựng và thử nghiệm ứng dụng
Để xây dựng ứng dụng chạy,
sam build
Để chạy thử
sam local invoke
đầu ra
Bạn sẽ thấy một cái gì đó tương tự như bên dưới tùy thuộc vào URL bạn đã tìm kiếm
Triển khai ứng dụng
Để triển khai ứng dụng cho lần chạy đầu tiên,
## Run selenium and chrome driver to scrape data from cloudbytes.dev
import time
import json
import os.path
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
def handler[event=None, context=None]:
chrome_options = webdriver.ChromeOptions[]
chrome_options.binary_location = "/opt/chrome/chrome"
chrome_options.add_argument["--headless"]
chrome_options.add_argument["--no-sandbox"]
chrome_options.add_argument["--disable-dev-shm-usage"]
chrome_options.add_argument["--disable-gpu"]
chrome_options.add_argument["--disable-dev-tools"]
chrome_options.add_argument["--no-zygote"]
chrome_options.add_argument["--single-process"]
chrome_options.add_argument["window-size=2560x1440"]
chrome_options.add_argument["--user-data-dir=/tmp/chrome-user-data"]
chrome_options.add_argument["--remote-debugging-port=9222"]
#chrome_options.add_argument["--data-path=/tmp/chrome-user-data"]
#chrome_options.add_argument["--disk-cache-dir=/tmp/chrome-user-data"]
chrome = webdriver.Chrome["/opt/chromedriver", options=chrome_options]
chrome.get["//cloudbytes.dev/"]
description = chrome.find_element[By.NAME, "description"].get_attribute["content"]
print[description]
return {
"statusCode": 200,
"body": json.dumps[
{
"message": description,
}
],
}
0Thao tác này sẽ bắt đầu triển khai tương tác với Lambda. Bạn có thể sử dụng các tùy chọn như hình bên dưới
Thao tác này cũng sẽ tạo một tệp
FROM public.ecr.aws/lambda/python:3.9 as stage
# Hack to install chromium dependencies
RUN yum install -y -q sudo unzip
# Find the version of latest stable build of chromium from below
# //omahaproxy.appspot.com/
# Then follow the instructions here in below URL
# to download old builds of Chrome/Chromium that are stable
# Current stable version of Chromium
ENV CHROMIUM_VERSION=1002910
# Install Chromium
COPY install-browser.sh /tmp/
RUN /usr/bin/bash /tmp/install-browser.sh
FROM public.ecr.aws/lambda/python:3.9 as base
COPY chrome-deps.txt /tmp/
RUN yum install -y $[cat /tmp/chrome-deps.txt]
# Install Python dependencies for function
COPY requirements.txt /tmp/
RUN python3 -m pip install --upgrade pip -q
RUN python3 -m pip install -r /tmp/requirements.txt -q
COPY --from=stage /opt/chrome /opt/chrome
COPY --from=stage /opt/chromedriver /opt/chromedriver
COPY app.py ${LAMBDA_TASK_ROOT}
CMD [ "app.handler" ]
1 chứa các cấu hình nàyLần tới sau khi bạn xây dựng ứng dụng, chỉ cần chạy
FROM public.ecr.aws/lambda/python:3.9 as stage
# Hack to install chromium dependencies
RUN yum install -y -q sudo unzip
# Find the version of latest stable build of chromium from below
# //omahaproxy.appspot.com/
# Then follow the instructions here in below URL
# to download old builds of Chrome/Chromium that are stable
# Current stable version of Chromium
ENV CHROMIUM_VERSION=1002910
# Install Chromium
COPY install-browser.sh /tmp/
RUN /usr/bin/bash /tmp/install-browser.sh
FROM public.ecr.aws/lambda/python:3.9 as base
COPY chrome-deps.txt /tmp/
RUN yum install -y $[cat /tmp/chrome-deps.txt]
# Install Python dependencies for function
COPY requirements.txt /tmp/
RUN python3 -m pip install --upgrade pip -q
RUN python3 -m pip install -r /tmp/requirements.txt -q
COPY --from=stage /opt/chrome /opt/chrome
COPY --from=stage /opt/chromedriver /opt/chromedriver
COPY app.py ${LAMBDA_TASK_ROOT}
CMD [ "app.handler" ]
2 để triển khai ứng dụngSau khi triển khai thành công, bạn sẽ thấy một cái gì đó tương tự như bên dưới. Lưu ý URL API trong đầu ra ở dưới cùng