【0基礎學爬蟲】爬蟲基礎之自動化工具 Playwright 的使用

来源:https://www.cnblogs.com/ikdl/archive/2023/04/28/17360960.html
-Advertisement-
Play Games

大數據時代,各行各業對數據採集的需求日益增多,網路爬蟲的運用也更為廣泛,越來越多的人開始學習網路爬蟲這項技術,K哥爬蟲此前已經推出不少爬蟲進階、逆向相關文章,為實現從易到難全方位覆蓋,特設【0基礎學爬蟲】專欄,幫助小白快速入門爬蟲,本期為自動化工具 playwright 的使用。 概述 上期文章中講 ...


0

大數據時代,各行各業對數據採集的需求日益增多,網路爬蟲的運用也更為廣泛,越來越多的人開始學習網路爬蟲這項技術,K哥爬蟲此前已經推出不少爬蟲進階、逆向相關文章,為實現從易到難全方位覆蓋,特設【0基礎學爬蟲】專欄,幫助小白快速入門爬蟲,本期為自動化工具 playwright 的使用。

概述

上期文章中講到了自動化工具 Selenium 的基本使用方法,也介紹了 Selenium 的優缺點。Selenium的功能非常強大,支持所有現代瀏覽器。但是 Selenium 使用起來十分不方便,我們需要提前安裝好瀏覽器,然後下載對應版本的驅動文件,當瀏覽器更新後驅動文件也得隨之更新。如果想要大規模且長期的採集數據,那麼部署 Selenium 時環境配置會是一個大問題。因此本期我們將介紹一款更加好用的自動化工具 Playwright 。

Playwright 的使用

介紹

Playwright是一個用於自動化Web瀏覽器測試和Web數據抓取的開源庫。它由Microsoft開發,支持Chrome、Firefox、Safari、Edge和WebKit瀏覽器。Playwright的一個主要特點是它能夠在所有主要的操作系統(包括Windows、Linux和macOS)上運行,並且它提供了一些強大的功能,如跨瀏覽器測試、支持無頭瀏覽器、並行執行測試、元素截圖和模擬輸入等。它主要有以下優勢:

  1. 相容多個瀏覽器,而且所有瀏覽器都使用相同的API。
  2. 速度快、穩定性高,即使在大型、複雜的Web應用程式中也可以運行。
  3. 支持無頭瀏覽器,因此可以在沒有可見界面的情況下運行測試,從而提高測試效率。
  4. 提供了豐富的 API,以便於執行各種操作,如截圖、模擬輸入、攔截網路請求等。

安裝

使用 Playwright 需要 Python版本在3.7以上。

安裝 Playwright 可以直接使用 pip 工具:

pip install playwright

安裝完成後需要進行初始化操作,安裝所需的瀏覽器。

playwright install

執行上述指令時,Playwright 會自動安裝多個瀏覽器(Chromium、Firefox 和 WebKit)並配置驅動,所以速度較慢。

使用

Playwright 支持同步與非同步兩種模式,這裡分開來進行講解。

同步

使用 Playwright 時可以選擇啟動安裝的三種瀏覽器(Chromium、Firefox 和 WebKit)中的一種。

from playwright.sync_api import sync_playwright

# 調用sync_playwright方法,返回瀏覽器上下文管理器
with sync_playwright() as p:
    # 創建谷歌瀏覽器示例,playwright預設啟動無頭模式,設置headless=False,即關閉無頭模式
    browser = p.chromium.launch(headless=False)
    # 新建選項卡
    page = browser.new_page()
    # 跳轉到目標網址
    page.goto("http://baidu.com")
    # 獲取頁面截圖
    page.screenshot(path='example.png')
    # 列印頁面的標題,也就是title節點中的文本信息
    print(page.title())
    # 關閉瀏覽器
    browser.close()
# 輸出:百度一下,你就知道

1

可以看到,Playwright 的使用也比較簡單,語法比較簡潔,而且瀏覽器的啟動速度以及運行速度也很快。

非同步

非同步代碼的編寫方法與同步基本一致,區別在於同步調用的是 sync_playwright,非同步調用的是 async_playwright。最終運行效果與同步一致。

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("http://baidu.com")
        # 列印網頁源代碼
        print(await page.content())
        await browser.close()

asyncio.run(main())

代碼生成

Playwright 提供了代碼生成功能,這個功能可以對我們在瀏覽器上的操作進行錄製並生成代碼,它可以有效提高程式的編寫效率。代碼生成功能需要使用 Playwright 命令行中的 codegen實現,codegen 命令存在如下主要參數:

-o :將生成的腳本保存到指定文件

--target :生成的語言,預設為 Python

--save-trace :記錄會話的跟蹤並將其保存到文件中

-b :要使用的瀏覽器,預設為 chromium

--timeout :設置頁面載入的超時時間

--user-agent :指定UA

--viewport-size :指定瀏覽器視窗大小

我們在命令行執行命令:playwright codegen -o script.py

執行命令後會彈出一個 chromium 瀏覽器與腳本視窗,當我們在瀏覽器上進行操作時,腳本視窗會根據我們的操作生成對應代碼。當我們操作結束後,關閉瀏覽器,在當前目錄下會生成一個 script.py 文件,該文件中就是我們在進行瀏覽器操作時,Playwright 錄製的代碼。我們運行該文件,就會發現它在復現我們之前的操作。

2

代碼生成功能的實用性其實較為一般,它只能實現比較簡單的操作,當遇到複雜操作時,生成的代碼就容易出現問題。最好的方式是使用代碼生成功能生成部分操作的代碼,然後再手動去修改它生成的代碼。

隔離

上一步中,我們使用代碼生成功能生成了一段代碼,我們會發現這段代碼中使用到了一個 new_context 方法,通過這個方法創建了一個 content ,然後再去進行其它操作。這個 new_content 方法其實是為了創建一個獨立的全新上下文環境,它的目的是為了防止多個測試用例並行時各個用例間不受干擾,當一個測試用例異常時不會影響到另一個。

browser = playwright.chromium.launch()
context = browser.new_context()
page = context.new_page()

定位器

Playwright 提供了多種定位器來幫助開發中定位元素。

page.get_by_role() :通過顯式和隱式可訪問性屬性進行定位。

page.get_by_text() :通過文本內容定位。

page.get_by_label() :通過關聯標簽的文本定位表單控制項。

page.get_by_placeholder() :按占位符定位輸入。

page.get_by_alt_text() :通過替代文本定位元素,通常是圖像。

page.get_by_title() :通過標題屬性定位元素。

page.get_by_test_id() :根據data-testid屬性定位元素(可以配置其他屬性)。

page.locator():拓展選擇器,可以使用 CSS 選擇器進行定位

使用定位器最好的方式就是上文中講到的利用代碼生成功能來生成定位代碼,然後手動去修改,這裡就不做嘗試。

選擇器

Playwright 支持 CSS、Xpath 和一些拓展選擇器,提供了一些比較方便的使用規則。

CSS 選擇器

# 匹配 button 標簽
page.locator('button').click()
# 根據 id 匹配,匹配 id 為 container 的節點
page.locator('#container').click()
# CSS偽類匹配,匹配可見的 button 按鈕 
page.locator("button:visible").click()
# :has-text 匹配任意內部包含指定文本的節點
page.locator(':has-text("Playwright")').click()
# 匹配 article 標簽內包含 products 文本的節點
page.locator('article:has-text("products")').click()
# 匹配 article 標簽下包含類名為 promo 的 div 標簽的節點
page.locator("article:has(div.promo)").click()

Xpath

page.locator("xpath=//button").click()
page.locator('xpath=//div[@class="container"]').click()

其它

# 根據文本匹配,匹配文本內容包含 name 的節點
page.locator('text=name').click()
# 匹配文本內容為 name 的節點
page.locator("text='name'").click()
# 正則匹配
page.locator("text=/name\s\w+word").click()
# 匹配第一個 button 按鈕
page.locator("button").locator("nth=0").click()
# 匹配第二個 button 按鈕
page.locator("button").locator("nth=-1").click()
# 匹配 id 為 name 的元素
page.locator('id=name')

等待

當進行 click 、fill 等操作時,Playwright 在採取行動之前會對元素執行一系列可操作性檢測,以確保這些行動能夠按預期進行。

如對元素進行 click 操作之前,Playwright 將確保:

元素附加到 DOM

元素可見

元素是穩定的,因為沒有動畫或完成動畫

元素接收事件,因為沒有被其他元素遮擋

元素已啟用

即使 Playwright 已經做了充分準備,但是也並不完全穩定,在實際項目中依舊容易出現因頁面載入導致事件沒有生效等問題,為了避免這些問題,需要自行設置等待。

# 固定等待1秒
page.wait_for_timeout(1000)
# 等待事件
page.wait_for_event(event)
# 等待載入狀態
page.get_by_role("button").click()
page.wait_for_load_state()

事件

添加/刪除事件

from playwright.sync_api import sync_playwright


def print_request_sent(request):
    print("Request sent: " + request.url)


def print_request_finished(request):
    print("Request finished: " + request.url)


with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
	# 添加事件 發起請求時列印URL
    page.on("request", print_request_sent)
    # 請求完成時列印URL
    page.on("requestfinished", print_request_finished)
    page.goto("https://baidu.com")
    # 刪除事件
    page.remove_listener("requestfinished", print_request_finished)
    browser.close()

反檢測

在 Selenium 的使用中,我們講到了自動化工具容易被網站檢測,也提供了一些繞過檢測的方案。這裡我們介紹一下 Playwright 的反檢測方案。

https://bot.sannysoft.com/ 為例,我們分別測試正常模式與無頭模式下的檢測結果。

正常模式:

3

無頭模式:

4

可以看到,正常模式下 WebDriver 一欄報紅,而無頭模式下更是慘不忍睹,基本上所有特征都被檢測到了。這些還只是最基本的檢測機制,自動化工具的弱點就暴露的很明顯了。

與 Selenium 一樣,繞過檢測主要還是針對網站的檢測機制來處理,主要就是在頁面載入之前通過執行 JS 代碼來修改一些瀏覽器特征。以無頭模式為例:

from playwright.sync_api import sync_playwright

with open('./stealth.min.js', 'r') as f:
    js = f.read()

with sync_playwright() as p:
    browser = p.chromium.launch()
    # 添加 UserAgent
    page = browser.new_page(
        user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
    )
    # 執行 JS 代碼
    page.add_init_script(js)
    page.goto("https://bot.sannysoft.com/")
    page.screenshot(path='example.png')
    browser.close()

這裡與 Selenium 反檢測方案一樣,執行 stealth.min.js 來隱藏特征( stealth.min.js 的來源與介紹參考上期文章)。最終結果如下圖:

5

可以看到,與真實瀏覽器訪問基本一致了。

總結

與 Selenium 相比,Playwright 最大的優點就是不需要手動安裝驅動,而且它擁有更好的性能與更多的功能。因此 在爬蟲領域,Playwright 是更好的選擇。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介 策略模式(Strategy Pattern)屬於行為型設計模式。將每一個演算法封裝到具有共同介面的獨立類中,根據需要來綁定策略,使得具體實現和策略解耦。 當你想使用對象中各種不同的演算法變體,使用if...else 所帶來的複雜和難以維護,可使用策略模式。或者當有許多相同類,它們僅在執行某些行為時 ...
  • 快速開始 發送請求 >>> import requests >>> r = requests.get('https://api.github.com/events') # GET >>> r = requests.post('https://httpbin.org/post', data={'key ...
  • 原文地址: JavaFx 生成二維碼工具類封裝 - Stars-One的雜貨小窩 之前星之音樂下載器有需要生成二維碼功能,當時用的是一個開源庫來實現的,但是沒過多久,發現那個庫依賴太多,有個http-client的依賴,把軟體都搞大了一倍,而且有時候開發的時候下載依賴還報錯,就想換個方案 於是在網上 ...
  • Golang GMP原理(1) 概念梳理 線程 線程一般指內核級線程,核心如下: 操作系統的最小調度單元 創建 銷毀 調度由內核完成,cpu要完成內核態與用戶態的轉換 可充分利用多核,實現並行 協程 協程線程對應 協程,又稱為用戶級線程,核心點如下: 與線程存在映射關係,為M:1 創建、銷毀、調度在 ...
  • 因所負責的系統使用的spring框架版本5.1.5.RELEASE線上上出過一個偶發的小事故,最後定位為spring-context中的一個bug導致的。 ...
  • 教程簡介 JasperReports入門教程 - 使用包含從環境設置,報告設計,編譯報告設計,填充報告,查看和列印報告,導出,參數,數據源開始的基礎知識到高級知識的初學者教程,簡單易學地設計和創建JasperReports ,欄位,表達式,變數,部分,組,樣式,Scriplets,子報告,圖表,Co ...
  • 來自 https://mp.weixin.qq.com/s?__biz=MzIzOTU0NTQ0MA==&mid=2247532967&idx=1&sn=19790c981aa33502aa1e3a8abe9cd064&chksm=e92a7ca8de5df5befc6cc534cbabdb847e ...
  • 教程簡介 Python 3入門教程 - 從基本概念開始,簡單易學地瞭解Python 3,包括Python 3語法面向對象語言,環境設置,基本語法,變數類型,基本運算符,決策,迴圈,方法,字元串等示例,列表,元組,字典,日期和時間,函數,模塊,文件I / O,工具/實用程式,異常處理,正則表達式,CG ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...