新一代爬蟲利器Python?Playwright詳解
Playwright是Microsoft在2020年初開源的新一代自動化測試工具,它的功能類似于Selenium、Pyppeteer等,都可以驅(qū)動瀏覽器進行各種自動化操作。它的功能也非常強大,對市面上主流瀏覽器都提供了支持,API功能簡潔又強大。雖然誕生的比較晚,但是發(fā)展得非常火熱。
在Pyppeteer已經(jīng)不再維護的年代,擁有Playwright這個開源工具是非常棒的選擇,文檔豐富,功能強大。
安裝方式
conda config --add channels conda-forge conda config --add channels microsoft conda install playwright playwright install
上述命令的具體運行過程是下載Playwright并將其打包為Chromium、Firefox和Webkit安裝瀏覽器二進制文件。
特點
- Playwright支持當(dāng)前所有主流瀏覽器,包括Chrome和Edge(基于Chromium)、Firefox、Safari(基于Webkit),提供完善的自動化控制的API。
- Playwright支持移動端頁面的測試,使用設(shè)備模擬技術(shù)可以在移動web瀏覽器中測試響應(yīng)式web應(yīng)用程序。
- Playwright支持所有瀏覽器的Headless模式和非Headless模式的測試。
- Playwright的安裝配置非常的簡單,安裝過程中會自動安裝對應(yīng)瀏覽器的驅(qū)動,不需要額外的配置WebDriver等。
- Playwright提供了大量的與自動化相關(guān)的API,當(dāng)頁面加載時會自動等待對應(yīng)節(jié)點的加載,大大的簡化了編寫API的難度。
使用方式
在python腳本中導(dǎo)入Playwright,并啟動3種瀏覽器(Chromium、Friefox和webkit)的其中一種。Playwright支持兩種編寫模式,一種是Pyppeter一樣的異步模式,另一種是像Selenium一樣的同步模式,我們可以根據(jù)實際的需要選擇不同的模式。
下面我們先來看看一個基本 同步模式的例子:
from playwright.sync_api import sync_playwright with sync_playwright() as p: for browser_type in [p.chromium, p.firefox, p.webkit]: browser = browser_type.launch(headless=False) page = browser.new_page() page.goto("https://www.baidu.com") page.screenshot(path=f"screenshot-{browser_type.name}.png") print(page.title()) browser.close()
首先在這里我們導(dǎo)入了sync_playwright方法,然后調(diào)用這個方法,該方法返回的是一個PlaywrightContextManager
對象,可以將其理解為瀏覽器的上下文管理器,這里將其賦值給變量p。接著調(diào)用PlaywrightContextManager對象的chromium、firefox、webkit瀏覽器實例,接著使用for循環(huán)依次去執(zhí)行它們的launch方法,同時設(shè)置headless為False。
這里有一個注意點:如果launch沒有設(shè)置為Flase,默認是無頭模式啟動瀏覽器,我們看不到任何的窗口。
launch方法返回的是一個瀏覽器(Browser)對象,我們將其復(fù)制為browser變量,然后調(diào)用new_page方法,相當(dāng)于是新建一個選顯卡,返回page對象并賦值給變量page,接下來就是調(diào)用page對象的一系列自動化API進行操作。當(dāng)頁面加載完畢之后生成截圖、控制臺輸出結(jié)果就退出,上面的代碼,調(diào)用了page對象的兩個方法:
1、screenshot
:參數(shù)傳一個文件的名稱,這樣截圖就會自動保存為該文件的名稱。
2、title
:返回頁面的標(biāo)題。
這時當(dāng)前目錄便會產(chǎn)生三個截圖文件,都是百度的首頁,文件名中都帶有瀏覽器的名稱,如圖所示:
控制臺運行結(jié)果:
百度一下,你就知道
百度一下,你就知道
百度一下,你就知道
除了上面所描述的同步模式之外,Playwright還支持異步模式,如果在項目中使用了asyncio,那么就應(yīng)該是考慮要采用異步模式,使用異步的API,寫法如下:
import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: for browser_type in [p.chromium, p.firefox, p.webkit]: browser = await browser_type.launch() page = await browser.new_page() await page.goto("https://www.baidu.com") await page.screenshot(path=f"screenshot-{browser_type.name}.png") print(await page.title()) await browser.close() asyncio.run(main())
從上面的代碼可以看出,整個寫法和同步模式是很相似的。
注意:
? 1、導(dǎo)入的是async_playwright方法
? 2、在寫法上添加 async/await 關(guān)鍵字。
代碼生成
Playwright還有一個強大的功能,那就是可以錄制我們在瀏覽器的操作,并將操作時的代碼自動生成。這個功能可以通過Playwright命令調(diào)用codegen來實現(xiàn),我們先看看codegen命令都有什么參數(shù)。
playwright codegen --help
結(jié)果類似如下:
Usage: npx playwright codegen [options] [url]
open page and generate code for user actions
Options:
-o, --output <file name> saves the generated script to a file
--target <language> language to generate, one of javascript, test, python, python-async, csharp (default:
"python")
-b, --browser <browserType> browser to use, one of cr, chromium, ff, firefox, wk, webkit (default: "chromium")
--channel <channel> Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc
--color-scheme <scheme> emulate preferred color scheme, "light" or "dark"
--device <deviceName> emulate device, for example "iPhone 11"
--geolocation <coordinates> specify geolocation coordinates, for example "37.819722,-122.478611"
--ignore-https-errors ignore https errors
--load-storage <filename> load context storage state from the file, previously saved with --save-storage
--lang <language> specify language / locale, for example "en-GB"
--proxy-server <proxy> specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"
--save-storage <filename> save context storage state at the end, for later use with --load-storage
--save-trace <filename> record a trace for the session and save it to a file
--timezone <time zone> time zone to emulate, for example "Europe/Rome"
--timeout <timeout> timeout for Playwright actions in milliseconds (default: "10000")
--user-agent <ua string> specify user agent string
--viewport-size <size> specify browser viewport size in pixels, for example "1280, 720"
-h, --help display help for commandExamples:
$ codegen
$ codegen --target=python
$ codegen -b webkit https://example.com
在上面可以看到有幾個選項,比如
- -o表示輸出代碼文件的名稱;
- –target表示所使用的語言,默認是python,即會生成同步模式的操作代碼,如果傳入的是python-async則會生成異步模式的操作代碼;
- -b表示使用的瀏覽器類型,默認是Chrome瀏覽器;
- –device可以模擬使用手機瀏覽器;
- –lang表示設(shè)置瀏覽器語言,
- –timeout可以設(shè)置頁面加載超時時間。
了解這些用法之后,我們就來嘗試啟動Chrome瀏覽器,然后將操作結(jié)果輸出到test3.py,命令如下:
playwright codegen -o test3.py --target python-async
可以看到瀏覽器還會高亮顯示正在操作的節(jié)點,同時還顯示了節(jié)點名稱。
在操作的過程中代碼是實時變化的。操作完畢之后即可關(guān)閉瀏覽器,Playwright會生成一個test3.py文件,內(nèi)容如下:
import asyncio from playwright.async_api import Playwright, async_playwright async def run(playwright: Playwright) -> None: browser = await playwright.chromium.launch(headless=False) context = await browser.new_context() # Open new page page = await context.new_page() # Go to https://www.baidu.com/ await page.goto("https://www.baidu.com/") # Click input[name="wd"] await page.click("input[name=\"wd\"]") # Click input[name="wd"] await page.click("input[name=\"wd\"]") # Fill input[name="wd"] await page.fill("input[name=\"wd\"]", "如何榜上富婆") # Click text=百度一下 # async with page.expect_navigation(url="https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%A6%82%E4%BD%95%E6%A6%9C%E4%B8%8A%E5%AF%8C%E5%A9%86&fenlei=256&rsv_pq=ca59e3ec000cf6aa&rsv_t=5f82kcndi6iqNSwqOVo5sd%2BHSoqhzQHKLGVs1HFegxx02UtWAA5gHQbWBfw&rqlang=cn&rsv_enter=0&rsv_dl=tb&rsv_sug3=24&rsv_sug1=14&rsv_sug7=100&rsv_btype=i&prefixsug=%25E5%25A6%2582%25E4%25BD%2595%25E6%25A6%259C%25E4%25B8%258A%25E5%25AF%258C%25E5%25A9%2586&rsp=4&inputT=8686&rsv_sug4=68370&rsv_jmp=fail"): async with page.expect_navigation(): await page.click("text=百度一下") # assert page.url == "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%A6%82%E4%BD%95%E6%A6%9C%E4%B8%8A%E5%AF%8C%E5%A9%86&fenlei=256&rsv_pq=ca59e3ec000cf6aa&rsv_t=5f82kcndi6iqNSwqOVo5sd%2BHSoqhzQHKLGVs1HFegxx02UtWAA5gHQbWBfw&rqlang=cn&rsv_enter=0&rsv_dl=tb&rsv_sug3=24&rsv_sug1=14&rsv_sug7=100&rsv_btype=i&prefixsug=%25E5%25A6%2582%25E4%25BD%2595%25E6%25A6%259C%25E4%25B8%258A%25E5%25AF%258C%25E5%25A9%2586&rsp=4&inputT=8686&rsv_sug4=68370" # Close page await page.close() # --------------------- await context.close() await browser.close() async def main() -> None: async with async_playwright() as playwright: await run(playwright) asyncio.run(main())
可以看到這里的代碼和我們之前編寫的代碼基本類似,而且也是完全可以運行的,運行之后就可以看到它又復(fù)現(xiàn)了我們剛才的動作。
另外這里的new_page并不是通過browser
調(diào)用的,而是通過context
變量調(diào)用的,context
又是通過Browser
對象調(diào)用的。這里的context變量相當(dāng)于一個BrowserContext
對象,它是一個類似于隱身模式的獨立上下文環(huán)境,其運行資源是隔離的,保證互不干擾。
選擇器
Playwright的文檔非常的豐富,可以直接參考https://playwright.dev/python/docs/selectors
事件監(jiān)聽
page對象提供了一個on方法,它可以用來監(jiān)聽頁面中各個事件,比如close
、console
、load
、request
、response
等等。
比如我們可以監(jiān)聽response事件,response事件可以在每次網(wǎng)絡(luò)請求得到響應(yīng)的時候觸發(fā),我們可以設(shè)置對應(yīng)的回調(diào)方法獲取對應(yīng)的Response的全部信息。
from playwright.sync_api import sync_playwright def on_response(response): print(f'Statue {response.status}:{response.url}') with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() page.on('response', on_response) page.goto('https://www.kenshujun.cn/') page.wait_for_load_state('networkidle') browser.close()
創(chuàng)建page對象之后,就開始監(jiān)聽response事件,同時將回調(diào)方法設(shè)置為on_response
,on_response
對象接受一個參數(shù),然后把狀態(tài)碼和連接都輸出來。
看可以看到這里輸出的結(jié)果與瀏覽器Network面板所加載的內(nèi)容是一樣的。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)通過公共鍵對字典列表排序算法示例
這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)通過公共鍵對字典列表排序算法,結(jié)合實例形式分析了Python基于operator模塊中的itemgetter()函數(shù)對字典進行排序的相關(guān)操作技巧,需要的朋友可以參考下2018-03-03python數(shù)據(jù)分析之單因素分析線性擬合及地理編碼
這篇文章主要介紹了python數(shù)據(jù)分析之單因素分析線性擬合及地理編碼,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06Python中查看變量的類型內(nèi)存地址所占字節(jié)的大小
這篇文章主要介紹了Python中查看變量的類型,內(nèi)存地址,所占字節(jié)的大小,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06