Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?

Yasoob là một tác giả, blogger và diễn giả công nghệ nổi tiếng. Anh ấy là tác giả của cuốn sách Python trung cấp và Dự án Python thực tế và thường xuyên viết blog tại https. //yasoob. tôi. Anh ấy hiện đang làm việc trên Azure tại Microsoft

Trong hướng dẫn trước, chúng ta đã học cách tận dụng khung Scrapy để giải quyết các tác vụ quét web phổ biến. Hôm nay chúng ta sẽ xem xét Selenium (với Python ❤️ ) trong hướng dẫn từng bước

Selenium đề cập đến một số dự án nguồn mở khác nhau được sử dụng để tự động hóa trình duyệt. Nó hỗ trợ các ràng buộc cho tất cả các ngôn ngữ lập trình chính, bao gồm cả ngôn ngữ yêu thích của chúng tôi. con trăn

Selenium API sử dụng giao thức WebDriver để kiểm soát các trình duyệt web như Chrome, Firefox hoặc Safari. Selenium có thể kiểm soát cả hai, phiên bản trình duyệt được cài đặt cục bộ, cũng như phiên bản chạy trên máy từ xa qua mạng

Ban đầu (và đó là khoảng 20 năm nay. ), Selenium được dành cho thử nghiệm xuyên trình duyệt, từ đầu đến cuối (thử nghiệm chấp nhận). Tuy nhiên, trong khi chờ đợi, nó đã được sử dụng chủ yếu như một nền tảng tự động hóa trình duyệt chung (e. g. để chụp ảnh màn hình), tất nhiên, cũng bao gồm mục đích thu thập dữ liệu web và quét web. Hiếm có gì tốt hơn trong việc "nói chuyện" với một trang web hơn là một trình duyệt thực sự phù hợp, phải không?

Selenium cung cấp nhiều cách để tương tác với các trang web, chẳng hạn như

  • nhấp vào nút
  • Điền biểu mẫu với dữ liệu
  • cuộn trang
  • Chụp ảnh màn hình
  • Thực thi mã JavaScript tùy chỉnh của riêng bạn

Nhưng lập luận mạnh mẽ nhất có lợi cho nó là khả năng xử lý các trang web theo cách tự nhiên, giống như bất kỳ trình duyệt nào sẽ. Điều này đặc biệt tỏa sáng với các trang web Ứng dụng một trang nặng về JavaScript. Nếu bạn loại bỏ một trang web như vậy bằng sự kết hợp truyền thống giữa máy khách HTTP và trình phân tích cú pháp HTML, thì hầu như bạn sẽ có rất nhiều tệp JavaScript nhưng không có quá nhiều dữ liệu để loại bỏ

Cài đặt

Mặc dù Selenium hỗ trợ một số công cụ trình duyệt, chúng tôi sẽ sử dụng Chrome cho ví dụ sau, vì vậy hãy đảm bảo rằng bạn đã cài đặt các gói sau

  • Trang tải xuống Chrome
  • Tệp nhị phân ChromeDriver khớp với phiên bản Chrome của bạn
  • Gói liên kết Selenium Python

Để cài đặt gói Selenium, như mọi khi, tôi khuyên bạn nên tạo một môi trường ảo (ví dụ: sử dụng virtualenv) và sau đó

pip install selenium

Bắt đầu nhanh

Khi bạn đã tải xuống, cả Chrome và ChromeDriver và cài đặt gói Selenium, bạn sẽ sẵn sàng khởi động trình duyệt

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')

Vì chúng tôi không định cấu hình rõ ràng chế độ không đầu, điều này thực sự sẽ hiển thị một cửa sổ Chrome thông thường, với một thông báo cảnh báo bổ sung ở trên cùng, cho biết rằng Chrome đang được kiểm soát bởi Selenium

Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?
Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?


Chế độ không đầu của Chrome

Chạy trình duyệt từ Selenium theo cách chúng tôi vừa làm đặc biệt hữu ích trong quá trình phát triển. Nó cho phép bạn quan sát chính xác những gì đang diễn ra và cách trang cũng như trình duyệt hoạt động trong ngữ cảnh mã của bạn. Tuy nhiên, khi bạn đã hài lòng với mọi thứ, tuy nhiên, bạn nên chuyển sang chế độ không đầu đã nói trong quá trình sản xuất

Ở chế độ đó, Selenium sẽ khởi động Chrome ở "nền" mà không có bất kỳ cửa sổ hoặc đầu ra hình ảnh nào. Hãy tưởng tượng một máy chủ sản xuất, chạy một vài phiên bản Chrome cùng lúc với tất cả các cửa sổ của chúng đang mở. Chà, các máy chủ thường có xu hướng bị bỏ quên khi nói đến mức độ "chú ý" của mọi người đối với giao diện người dùng của họ - thật tội nghiệp ☹️ - nhưng nghiêm túc mà nói, chẳng ích gì khi lãng phí tài nguyên GUI mà không có lý do

May mắn thay, kích hoạt chế độ không đầu chỉ mất một vài lá cờ

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)

Chúng tôi chỉ cần khởi tạo một đối tượng

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
8, đặt trường
from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
9 của nó thành
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
0 và chuyển nó tới hàm tạo WebDriver của chúng tôi. Xong

Thuộc tính trang WebDriver

Dựa trên ví dụ về chế độ không đầu của chúng tôi, hãy xem toàn bộ Mario và xem trang web của Nintendo

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()

Khi bạn chạy tập lệnh đó, bạn sẽ nhận được một vài thông báo gỡ lỗi liên quan đến trình duyệt và cuối cùng là mã HTML của nintendo. com. Đó là do cuộc gọi

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
1 của chúng tôi truy cập vào trường
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
2 của trình điều khiển, trường này chứa chính tài liệu HTML của trang web mà chúng tôi đã yêu cầu lần cuối

Hai trường WebDriver thú vị khác là

  • from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    options = Options()
    options.headless = True
    options.add_argument("--window-size=1920,1200")
    
    driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
    
    3, để lấy tiêu đề của trang
  • from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    options = Options()
    options.headless = True
    options.add_argument("--window-size=1920,1200")
    
    driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
    
    4, để lấy URL hiện tại (điều này có thể hữu ích khi có chuyển hướng trên trang web và bạn cần URL cuối cùng)

Có thể tìm thấy danh sách đầy đủ các thuộc tính trong tài liệu của WebDriver

yếu tố định vị

Để cạo/trích xuất dữ liệu, trước tiên bạn cần biết dữ liệu đó ở đâu. Vì lý do đó, định vị các phần tử trang web là một trong những tính năng rất quan trọng của việc quét web. Đương nhiên, Selenium đi kèm với tính năng vượt trội đó (e. g. các trường hợp thử nghiệm cần đảm bảo rằng một phần tử cụ thể có/không có trên trang)

Có khá nhiều cách tiêu chuẩn để người ta có thể tìm thấy một phần tử cụ thể trên một trang. Ví dụ, bạn có thể

  • tìm kiếm theo tên của thẻ
  • bộ lọc cho một lớp HTML hoặc ID HTML cụ thể
  • hoặc sử dụng bộ chọn CSS hoặc biểu thức XPath

Riêng đối với biểu thức XPath, tôi thực sự khuyên bạn nên xem bài viết của chúng tôi về cách biểu thức XPath có thể giúp bạn lọc cây DOM. Nếu bạn chưa hoàn toàn quen thuộc với nó, nó thực sự cung cấp phần giới thiệu đầu tiên rất hữu ích về các biểu thức XPath và cách sử dụng chúng

Như thường lệ, cách dễ nhất để xác định vị trí phần tử là mở công cụ phát triển Chrome của bạn và kiểm tra phần tử bạn cần. Một phím tắt thú vị cho việc này là đánh dấu phần tử bạn muốn bằng chuột rồi nhấn Ctrl + Shift + C hoặc trên macOS Cmd + Shift + C thay vì phải nhấp chuột phải và chọn

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
5 mỗi lần

Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?
Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?


Khi bạn đã tìm thấy phần tử trong cây DOM, bạn có thể thiết lập phương pháp tốt nhất là gì để xử lý phần tử theo chương trình. Ví dụ: bạn có thể nhấp chuột phải vào phần tử trong trình kiểm tra và sao chép biểu thức XPath tuyệt đối hoặc bộ chọn CSS của nó

Các phương thức find_element

WebDriver cung cấp hai phương thức chính để tìm phần tử

  • from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    options = Options()
    options.headless = True
    options.add_argument("--window-size=1920,1200")
    
    driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
    
    6
  • from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    options = Options()
    options.headless = True
    options.add_argument("--window-size=1920,1200")
    
    driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
    
    7

Chúng khá giống nhau, với sự khác biệt là cái trước tìm kiếm một phần tử duy nhất, nó sẽ trả về, trong khi cái sau sẽ trả về một danh sách tất cả các phần tử được tìm thấy

Cả hai phương thức đều hỗ trợ tám loại tìm kiếm khác nhau, được biểu thị bằng lớp

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
8

TypeDescriptionDOM SampleExample
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
9Searches for elements based on their HTML ID
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
0
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
1
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
2Searches for elements based on their name attribute
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
3
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
4
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
5Searches for elements based on an XPath expression
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
6
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
7
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
8Searches for anchor elements based on a match of their text content
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
9
<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>
0
<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>
1Searches for anchor elements based on a sub-string match of their text content
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
driver.get("https://www.nintendo.com/")
print(driver.page_source)
driver.quit()
9
<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>
3
<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>
4Searches for elements

Một mô tả đầy đủ về các phương pháp có thể được tìm thấy ở đây

ví dụ về find_element

Giả sử, chúng ta có tài liệu HTML sau

<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>

và chúng tôi muốn chọn phần tử

<html>
    <head>
        .. some stuff
    head>
    <body>
        <h1 class="someclass" id="greatID">Super titleh1>
    body>
html>
5. Ở đây, năm ví dụ sau đây sẽ giống hệt nhau trong những gì chúng trả về

h1 = driver.find_element(By.NAME, 'h1')
h1 = driver.find_element(By.CLASS_NAME, 'someclass')
h1 = driver.find_element(By.XPATH, '//h1')
h1 = driver.find_element(By.XPATH, '/html/body/h1')
h1 = driver.find_element(By.ID, 'greatID')

Một ví dụ khác có thể là, để chọn tất cả các thẻ neo/liên kết trong trang. Vì chúng tôi muốn có nhiều hơn một phần tử, chúng tôi sẽ sử dụng

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
7 ở đây (vui lòng lưu ý số nhiều)

all_links = driver.find_elements(By.TAG_NAME, 'a')

Một số phần tử không thể truy cập dễ dàng bằng ID hoặc lớp đơn giản và đó là lúc bạn cần biểu thức XPath. Bạn cũng có thể có nhiều phần tử với cùng một lớp và đôi khi có cả ID, mặc dù phần tử sau được coi là duy nhất

XPath là cách yêu thích của tôi để định vị các thành phần trên trang web. Đó là một cách mạnh mẽ để trích xuất bất kỳ phần tử nào trên một trang, dựa trên vị trí tuyệt đối của nó trong DOM hoặc liên quan đến phần tử khác

Phần tử Web Selenium

Một

h1 = driver.find_element(By.NAME, 'h1')
h1 = driver.find_element(By.CLASS_NAME, 'someclass')
h1 = driver.find_element(By.XPATH, '//h1')
h1 = driver.find_element(By.XPATH, '/html/body/h1')
h1 = driver.find_element(By.ID, 'greatID')
5 là một đối tượng Selenium đại diện cho một phần tử HTML

Có nhiều hành động mà bạn có thể thực hiện trên các đối tượng đó, đây là những hành động hữu ích nhất

  • Truy cập văn bản của phần tử với thuộc tính
    h1 = driver.find_element(By.NAME, 'h1')
    h1 = driver.find_element(By.CLASS_NAME, 'someclass')
    h1 = driver.find_element(By.XPATH, '//h1')
    h1 = driver.find_element(By.XPATH, '/html/body/h1')
    h1 = driver.find_element(By.ID, 'greatID')
    
    6
  • Nhấp vào phần tử bằng
    h1 = driver.find_element(By.NAME, 'h1')
    h1 = driver.find_element(By.CLASS_NAME, 'someclass')
    h1 = driver.find_element(By.XPATH, '//h1')
    h1 = driver.find_element(By.XPATH, '/html/body/h1')
    h1 = driver.find_element(By.ID, 'greatID')
    
    7
  • Truy cập một thuộc tính với
    h1 = driver.find_element(By.NAME, 'h1')
    h1 = driver.find_element(By.CLASS_NAME, 'someclass')
    h1 = driver.find_element(By.XPATH, '//h1')
    h1 = driver.find_element(By.XPATH, '/html/body/h1')
    h1 = driver.find_element(By.ID, 'greatID')
    
    8
  • Gửi văn bản đến một đầu vào với
    h1 = driver.find_element(By.NAME, 'h1')
    h1 = driver.find_element(By.CLASS_NAME, 'someclass')
    h1 = driver.find_element(By.XPATH, '//h1')
    h1 = driver.find_element(By.XPATH, '/html/body/h1')
    h1 = driver.find_element(By.ID, 'greatID')
    
    9

Có một số phương pháp thú vị khác như

all_links = driver.find_elements(By.TAG_NAME, 'a')
0. Điều này trả về
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
0 nếu một phần tử hiển thị cho người dùng và có thể chứng minh hữu ích để tránh honeypots (e. g. các yếu tố đầu vào ẩn cố ý). Honeypots là cơ chế được chủ sở hữu trang web sử dụng để phát hiện bot. Ví dụ: nếu đầu vào HTML có thuộc tính
all_links = driver.find_elements(By.TAG_NAME, 'a')
2 như thế này

<input type="hidden" id="custId" name="custId" value="">

Giá trị đầu vào này được cho là để trống. Nếu một bot đang truy cập một trang và tin rằng nó cần điền giá trị cho tất cả các thành phần đầu vào, thì nó cũng sẽ điền đầu vào ẩn. Người dùng hợp pháp sẽ không bao giờ cung cấp giá trị cho trường ẩn đó vì nó không được trình duyệt hiển thị ngay từ đầu

Đó là một hũ mật ong cổ điển

ví dụ đầy đủ

Dưới đây là một ví dụ đầy đủ về việc sử dụng các phương thức API Selenium mà chúng tôi vừa trình bày

Chúng ta sẽ đăng nhập vào Hacker News

Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?
Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?


Tất nhiên, bản thân việc xác thực với Hacker News không thực sự hữu ích. Tuy nhiên, bạn có thể tưởng tượng việc tạo bot để tự động đăng liên kết đến bài đăng blog mới nhất của bạn

Để xác thực chúng ta cần

  • Truy cập trang đăng nhập bằng cách sử dụng
    all_links = driver.find_elements(By.TAG_NAME, 'a')
    
    3
  • Chọn trường nhập tên người dùng bằng cách sử dụng
    all_links = driver.find_elements(By.TAG_NAME, 'a')
    
    4 và sau đó gọi
    all_links = driver.find_elements(By.TAG_NAME, 'a')
    
    5 để gửi văn bản đến trường
  • Thực hiện theo quy trình tương tự với trường nhập mật khẩu
  • Chọn nút đăng nhập (tất nhiên là _______2_______6) và nhấp vào nút đó bằng cách sử dụng
    h1 = driver.find_element(By.NAME, 'h1')
    h1 = driver.find_element(By.CLASS_NAME, 'someclass')
    h1 = driver.find_element(By.XPATH, '//h1')
    h1 = driver.find_element(By.XPATH, '/html/body/h1')
    h1 = driver.find_element(By.ID, 'greatID')
    
    7

Nên được dễ dàng phải không?

driver.get("https://news.ycombinator.com/login")

login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
submit = driver.find_element_by_xpath("//input[@value='login']").click()

Dễ dàng, phải không? . Làm thế nào để chúng tôi biết nếu chúng tôi đã đăng nhập?

Chúng ta có thể thử một vài điều

  • Kiểm tra thông báo lỗi (chẳng hạn như "Sai mật khẩu")
  • Kiểm tra một thành phần trên trang chỉ được hiển thị sau khi đăng nhập

Vì vậy, chúng tôi sẽ kiểm tra nút đăng xuất. Nút đăng xuất có ID

all_links = driver.find_elements(By.TAG_NAME, 'a')
8 (dễ dàng)

Chúng tôi không thể chỉ kiểm tra xem phần tử có phải là

all_links = driver.find_elements(By.TAG_NAME, 'a')
9 hay không vì
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=options, executable_path=DRIVER_PATH)
6 sẽ đưa ra một ngoại lệ, nếu phần tử không được tìm thấy trong DOM. Vì vậy, chúng tôi phải sử dụng khối try/ngoại trừ và bắt ngoại lệ
<input type="hidden" id="custId" name="custId" value="">
1

# dont forget from selenium.common.exceptions import NoSuchElementException
try:
    logout_button = driver.find_element_by_id("logout")
    print('Successfully logged in')
except NoSuchElementException:
    print('Incorrect login/password')

Rực rỡ, hoạt động

Chụp ảnh màn hình

Cái hay của cách tiếp cận trình duyệt, như Selenium, là chúng ta không chỉ lấy dữ liệu và cây DOM, mà - là một trình duyệt - nó còn hiển thị đúng và đầy đủ toàn bộ trang. Tất nhiên, điều này cũng cho phép chụp ảnh màn hình và Selenium được chuẩn bị đầy đủ tại đây

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
0

Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?
Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?


Một cuộc gọi duy nhất và chúng tôi có ảnh chụp màn hình trang của chúng tôi. Bây giờ, nếu điều đó không thú vị

Xin lưu ý, một số thứ vẫn có thể sai hoặc cần chỉnh sửa khi bạn chụp ảnh màn hình bằng Selenium. Trước tiên, bạn phải đảm bảo rằng kích thước cửa sổ được đặt chính xác. Sau đó, bạn cần đảm bảo rằng mọi lệnh gọi HTTP không đồng bộ được thực hiện bởi mã JavaScript giao diện người dùng đã kết thúc và trang được hiển thị đầy đủ

Trong trường hợp Hacker News của chúng tôi, nó đơn giản và chúng tôi không phải lo lắng về những vấn đề này

💡 Bạn có biết, ScrapingBee cung cấp API ảnh chụp màn hình chuyên dụng không? . Không có gì tuyệt vời hơn việc gửi yêu cầu ảnh chụp màn hình của bạn tới API và ngồi thưởng thức một ly ca cao nóng ☕

Chờ đợi một yếu tố có mặt

Xử lý một trang web sử dụng nhiều JavaScript để hiển thị nội dung của nó có thể khó khăn. Ngày nay, ngày càng có nhiều trang web sử dụng các framework như Angular, React và Vue. js cho giao diện người dùng của họ. Các khung giao diện người dùng này rất phức tạp để xử lý vì chúng không chỉ phục vụ mã HTML mà còn có một bộ mã JavaScript khá phức tạp liên quan, thay đổi cây DOM một cách nhanh chóng và gửi nhiều thông tin không đồng bộ trong

Điều đó có nghĩa là, chúng tôi không thể gửi yêu cầu và thu thập dữ liệu ngay lập tức mà chúng tôi có thể phải đợi cho đến khi JavaScript hoàn thành công việc của mình. Thông thường có hai cách để tiếp cận điều đó

  • Sử dụng
    <input type="hidden" id="custId" name="custId" value="">
    
    2 trước khi chụp ảnh màn hình
  • Sử dụng một đối tượng
    <input type="hidden" id="custId" name="custId" value="">
    
    3

Nếu bạn sử dụng

<input type="hidden" id="custId" name="custId" value="">
2, bạn sẽ phải sử dụng độ trễ hợp lý nhất cho trường hợp sử dụng của mình. Vấn đề là, bạn đang đợi quá lâu hoặc không đủ lâu và cả hai đều không lý tưởng. Ngoài ra, trang web có thể tải chậm hơn trên kết nối ISP dân cư của bạn so với khi mã của bạn đang chạy trong sản xuất trong trung tâm dữ liệu. Với
<input type="hidden" id="custId" name="custId" value="">
3, bạn thực sự không cần phải tính đến điều đó. Nó sẽ chỉ đợi chừng nào cần thiết cho đến khi phần tử mong muốn xuất hiện (hoặc nó hết thời gian chờ)

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
1

Điều này sẽ đợi cho đến khi phần tử có ID HTML

<input type="hidden" id="custId" name="custId" value="">
6 xuất hiện hoặc đã hết thời gian chờ năm giây. Có khá nhiều loại Điều kiện ngoại lệ khác

  • <input type="hidden" id="custId" name="custId" value="">
    
    7
  • <input type="hidden" id="custId" name="custId" value="">
    
    8
  • <input type="hidden" id="custId" name="custId" value="">
    
    9
  • driver.get("https://news.ycombinator.com/login")
    
    login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
    password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
    submit = driver.find_element_by_xpath("//input[@value='login']").click()
    
    0

Tất nhiên, có thể tìm thấy danh sách đầy đủ về Chờ đợi và Điều kiện dự kiến ​​của nó trong tài liệu về Selenium

Tuy nhiên, có một công cụ trình duyệt đầy đủ theo ý của chúng tôi, không chỉ có nghĩa là chúng tôi có thể, ít nhiều, dễ dàng xử lý mã JavaScript do trang web chạy, mà còn có nghĩa là chúng tôi có khả năng chạy JavaScript tùy chỉnh của riêng mình. Hãy kiểm tra điều đó tiếp theo

Thực thi JavaScript

Cũng giống như với , chúng ta có thể tận dụng tối đa công cụ JavaScript của trình duyệt của mình. Điều đó có nghĩa là chúng ta có thể thêm và thực thi mã tùy ý và chạy nó trong ngữ cảnh của trang web. Bạn muốn chụp ảnh màn hình của một phần nằm dưới trang một chút?

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
2

Hoặc bạn muốn làm nổi bật tất cả các thẻ neo bằng đường viền?

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
3

Một lợi ích bổ sung của

driver.get("https://news.ycombinator.com/login")

login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
submit = driver.find_element_by_xpath("//input[@value='login']").click()
2 là, nó trả về giá trị của biểu thức bạn đã chuyển. Tóm lại, đoạn mã sau sẽ chuyển thẳng tiêu đề tài liệu của chúng ta đến biến
driver.get("https://news.ycombinator.com/login")

login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
submit = driver.find_element_by_xpath("//input[@value='login']").click()
4 của chúng ta

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
4

Không tệ, phải không?

Có thể trả về giá trị,

driver.get("https://news.ycombinator.com/login")

login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
submit = driver.find_element_by_xpath("//input[@value='login']").click()
2 có tính chất đồng bộ. Tất nhiên, nếu bạn không cần đợi một giá trị, bạn cũng có thể sử dụng đối tác không đồng bộ của nó là
driver.get("https://news.ycombinator.com/login")

login = driver.find_element_by_xpath("//input").send_keys(USERNAME)
password = driver.find_element_by_xpath("//input[@type='password']").send_keys(PASSWORD)
submit = driver.find_element_by_xpath("//input[@value='login']").click()
6

Sử dụng proxy với Selenium Wire

Thật không may, việc xử lý proxy Selenium khá cơ bản. Ví dụ: nó không thể xử lý xác thực proxy ngay lập tức

Để giải quyết vấn đề này, bạn có thể sử dụng Selenium Wire. Gói này mở rộng các ràng buộc của Selenium và cung cấp cho bạn quyền truy cập vào tất cả các yêu cầu cơ bản do trình duyệt thực hiện. Nếu bạn cần sử dụng Selenium với proxy có xác thực thì đây là gói bạn cần

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
5

Đoạn mã này chỉ cho bạn cách nhanh chóng sử dụng trình duyệt không đầu của bạn sau một proxy

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
6

Chặn hình ảnh và JavaScript

Có toàn bộ bộ tính năng tiêu chuẩn của trình duyệt trong tầm tay của chúng tôi, thực sự đưa việc cạo lên cấp độ tiếp theo. Chúng tôi có các trang được hiển thị đầy đủ, cho phép chúng tôi chụp ảnh màn hình, JavaScript của trang web được thực thi đúng trong ngữ cảnh phù hợp và hơn thế nữa

Tuy nhiên, đôi khi, chúng tôi thực sự không cần tất cả các tính năng này. Ví dụ: nếu chúng tôi không chụp ảnh màn hình, thì việc tải xuống nhất thiết phải tất cả các hình ảnh sẽ chẳng ích lợi gì. May mắn thay, Selenium và WebDriver cũng đã hỗ trợ chúng tôi ở đây

Bạn có nhớ lớp học

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
8 trước đây không? . Ví dụ: nếu chúng tôi muốn tắt tải hình ảnh và thực thi mã JavaScript, chúng tôi sẽ sử dụng các tùy chọn sau

from selenium import webdriver

DRIVER_PATH = '/path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://google.com')
7

Phần kết luận

Tôi hy vọng bạn thích bài đăng trên blog này. Bây giờ bạn đã hiểu rõ về cách thức hoạt động của Selenium API trong Python. Nếu bạn muốn biết thêm về cách quét web bằng Python, vui lòng xem hướng dẫn quét web Python chung của chúng tôi

Một bài đọc thú vị khác là hướng dẫn của chúng tôi về Puppeteer với Python. Puppeteer là một API để điều khiển Chrome, nó khá mạnh hơn Selenium (nó được duy trì trực tiếp bởi nhóm Google)

Selenium thường cần thiết để trích xuất dữ liệu từ các trang web sử dụng nhiều JavaScript. Vấn đề là việc chạy nhiều phiên bản Selenium/Headless Chrome trên quy mô lớn rất khó. Đây là một trong những điều chúng tôi giải quyết với ScrapingBee, API quét web của chúng tôi. API của chúng tôi là một nền tảng quét SaaS, cho phép dễ dàng mở rộng quy mô công việc thu thập thông tin của bạn nhưng cũng biết cách xử lý vượt trội các chủ đề liên quan đến quét khác, chẳng hạn như proxy và quản lý kết nối và điều chỉnh yêu cầu

Selenium cũng là một công cụ tuyệt vời để tự động hóa hầu hết mọi thứ trên web

Nếu bạn thực hiện các tác vụ lặp đi lặp lại, chẳng hạn như điền vào biểu mẫu hoặc kiểm tra thông tin đằng sau biểu mẫu đăng nhập mà trang web không có API, thì có lẽ nên tự động hóa nó bằng Selenium, đừng quên truyện tranh xkcd này

Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?
Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?


Làm thế nào để bạn tự động hóa một trang web bằng Selenium Python?

Kevin Sahin

Kevin đã làm việc trong ngành quét web 10 năm trước khi đồng sáng lập ScrapingBee. Ông cũng là tác giả của Java Web Scraping Handbook.

Làm cách nào để tự động hóa một trang web bằng Selenium Python?

1. 1 Liên kết Selenium trong Python. Các liên kết Selenium Python cung cấp API thuận tiện để truy cập Trình điều khiển web Selenium như Firefox, Chrome, v.v. Pip cài đặt Selenium
1. 2 trình điều khiển web. Selenium yêu cầu trình điều khiển web để giao tiếp với trình duyệt đã chọn. Trình điều khiển web là một gói để tương tác với trình duyệt web

Làm cách nào để sử dụng Selenium để tự động hóa bất kỳ trang web nào?

Các bước để tự động đăng nhập bằng Selenium WebDriver .
Tạo một phiên bản Selenium WebDriver
Cấu hình trình duyệt nếu cần
Điều hướng đến trang web được yêu cầu
Xác định vị trí phần tử web có liên quan
Thực hiện hành động trên phần tử web
Xác minh và xác thực hành động

Chúng ta có thể tự động hóa ứng dụng web bằng Python không?

Bạn đã biết rằng Python có thể làm mọi thứ mà trình duyệt web có thể làm và hơn thế nữa. Bạn có thể dễ dàng viết các tập lệnh để kiểm soát các phiên bản trình duyệt ảo chạy trên đám mây. Bạn có thể tạo các bot tương tác với người dùng thực hoặc điền vào các biểu mẫu mà không cần suy nghĩ. Đi ra ngoài và tự động hóa.

Làm cách nào để mở một trang web bằng Selenium Python?

Để mở một URL nhất định trong cửa sổ trình duyệt bằng Selenium cho Python, gọi phương thức get() trên đối tượng trình điều khiển và chuyển URL làm đối số cho phương thức get().