Pyppeteer 的使用


1.Pyppeteer 介紹

Puppeteer 是 Google 基於 Node.js 開發的一個工具,有了它我們可以通過 JavaScript 來控制 Chrome 瀏覽器的一些操作,當然也可以用作網絡爬蟲上,其 API 極其完善,功能非常強大,Selenium 當然同樣可以做到。

而 Pyppeteer 又是什么呢?它實際上是 Puppeteer 的 Python 版本的實現,但它不是 Google 開發的,是一位來自於日本的工程師依據 Puppeteer 的一些功能開發出來的非官方版本。

在 Pyppetter 中,實際上它背后也是有一個類似 Chrome 瀏覽器的 Chromium 瀏覽器在執行一些動作進行網頁渲染

Pyppeteer 就是依賴於 Chromium 這個瀏覽器來運行的。那么有了 Pyppeteer 之后,我們就可以免去那些煩瑣的環境配置等問題。如果第一次運行的時候,Chromium 瀏覽器沒有安裝,那么程序會幫我們自動安裝和配置,就免去了煩瑣的環境配置等工作。另外 Pyppeteer 是基於 Python 的新特性 async 實現的,所以它的一些執行也支持異步操作,效率相對於 Selenium 來說也提高了。

2.安裝

首先就是安裝問題了,由於 Pyppeteer 采用了 Python 的 async 機制,所以其運行要求的 Python 版本為 3.5 及以上。

pip3 install pyppeteer

好了,安裝完成之后我們在命令行下測試:

import pyppeteer

2.1 快速上手

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq


async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto('http://news.baidu.com/')
    await page.waitForSelector('a')
    doc = pq(await page.content())
    names = [item.text() for item in doc('a').items()]
    print('Names:', names)
    await browser.close()


asyncio.get_event_loop().run_until_complete(main())

那么這里面的具體過程發生了什么?我們來逐行看下。

  • launch 方法會新建一個 Browser 對象,其執行后最終會得到一個 Browser 對象,然后賦值給 browser。這一步就相當於啟動了瀏覽器。
  • 然后 browser 調用 newPage 方法相當於瀏覽器中新建了一個選項卡,同時新建了一個 Page 對象,這時候新啟動了一個選項卡,但是還未訪問任何頁面,瀏覽器依然是空白。
  • 隨后 Page 對象調用了 goto 方法就相當於在瀏覽器中輸入了這個 URL,瀏覽器跳轉到了對應的頁面進行加載。
  • Page 對象調用 waitForSelector 方法,傳入選擇器,那么頁面就會等待選擇器所-對應的節點信息加載出來,如果加載出來了,立即返回,否則會持續等待直到超時。此時如果順利的話,頁面會成功加載出來。
  • 頁面加載完成之后再調用 content 方法,可以獲得當前瀏覽器頁面的源代碼,這就是 JavaScript 渲染后的結果。
  • 然后進一步的,我們用 pyquery 進行解析並提取頁面的電影名稱,就得到最終結果了。
    另外其他的一些方法如調用 asyncio 的 get_event_loop 等方法的相關操作則屬於 Python 異步 async 相關的內容了,你如果不熟悉可以了解下前面所講的異步相關知識。

2.2 設定了瀏覽器窗口大小

import asyncio
from pyppeteer import launch
width, height = 1366, 768
async def main():
   browser = await launch()
   page = await browser.newPage()
   await page.setViewport({'width': width, 'height': height})
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   await page.waitForSelector('.item .name')
   await asyncio.sleep(2)
   await page.screenshot(path='example.png')
   dimensions = await page.evaluate('''() => {
       return {
           width: document.documentElement.clientWidth,
           height: document.documentElement.clientHeight,
           deviceScaleFactor: window.devicePixelRatio,
       }
   }''')

   print(dimensions)
   await browser.close()
asyncio.get_event_loop().run_until_complete(main())

這里我們又用到了幾個新的 API,完成了頁面窗口大小設置、網頁截圖保存、執行 JavaScript 並返回對應數據。

首先 screenshot 方法可以傳入保存的圖片路徑,另外還可以指定保存格式 type、清晰度 quality、是否全屏 fullPage、裁切 clip 等各個參數實現截圖。

截圖的樣例如下:

 

 

 

可以看到它返回的就是 JavaScript 渲染后的頁面,和我們在瀏覽器中看到的結果是一模一樣的。

最后我們又調用了 evaluate 方法執行了一些 JavaScript,JavaScript 傳入的是一個函數,使用 return 方法返回了網頁的寬高、像素大小比率三個值,最后得到的是一個 JSON 格式的對象,內容如下:

{'width': 1366, 'height': 768, 'deviceScaleFactor': 1}

OK,實例就先感受到這里,還有太多太多的功能還沒提及。

總之利用 Pyppeteer 我們可以控制瀏覽器執行幾乎所有動作,想要的操作和功能基本都可以實現,用它來自由地控制爬蟲當然就不在話下了。

3.詳細用法

了解了基本的實例之后,我們再來梳理一下 Pyppeteer 的一些基本和常用操作。Pyppeteer 的幾乎所有功能都能在其官方文檔的 API Reference 里面找到,鏈接為:https://miyakogi.github.io/pyppeteer/reference.html,用到哪個方法就來這里查詢就好了,參數不必死記硬背,即用即查就好。

3.1 launch

使用 Pyppeteer 的第一步便是啟動瀏覽器,首先我們看下怎樣啟動一個瀏覽器,其實就相當於我們點擊桌面上的瀏覽器圖標一樣,把它運行起來。用 Pyppeteer 完成同樣的操作,只需要調用 launch 方法即可。

我們先看下 launch 方法的 API,鏈接為:https://miyakogi.github.io/pyppeteer/reference.html#pyppeteer.launcher.launch,其方法定義如下:

pyppeteer.launcher.launch(options: dict = None, **kwargs) → pyppeteer.browser.Browser

可以看到它處於 launcher 模塊中,參數沒有在聲明中特別指定,返回類型是 browser 模塊中的 Browser 對象,另外觀察源碼發現這是一個 async 修飾的方法,所以調用它的時候需要使用 await。

接下來看看它的參數:

  • ignoreHTTPSErrors (bool):是否要忽略 HTTPS 的錯誤,默認是 False。
  • headless (bool):是否啟用 Headless 模式,即無界面模式,如果 devtools 這個參數是 True 的話,那么該參數就會被設置為 False,否則為 True,即默認是開啟無界面模式的。
  • executablePath (str):可執行文件的路徑,如果指定之后就不需要使用默認的 Chromium 了,可以指定為已有的 Chrome 或 Chromium。
  • slowMo (int|float):通過傳入指定的時間,可以減緩 Pyppeteer 的一些模擬操作。
    args (List[str]):在執行過程中可以傳入的額外參數。
  • ignoreDefaultArgs (bool):不使用 Pyppeteer 的默認參數,如果使用了這個參數,那么最好通過 args 參數來設定一些參數,否則可能會出現一些意想不到的問題。這個參數相對比較危險,慎用。
  • handleSIGINT (bool):是否響應 SIGINT 信號,也就是可以使用 Ctrl + C 來終止瀏覽器程序,默認是 True。
  • handleSIGTERM (bool):是否響應 SIGTERM 信號,一般是 kill 命令,默認是 True。
  • handleSIGHUP (bool):是否響應 SIGHUP 信號,即掛起信號,比如終端退出操作,默認是 True。
  • dumpio (bool):是否將 Pyppeteer 的輸出內容傳給 process.stdout 和 process.stderr 對象,默認是 False。
  • userDataDir (str):即用戶數據文件夾,即可以保留一些個性化配置和操作記錄。
    env (dict):環境變量,可以通過字典形式傳入。
  • devtools (bool):是否為每一個頁面自動開啟調試工具,默認是 False。如果這個參數設置為 True,那么 headless 參數就會無效,會被強制設置為 False。
  • logLevel (int|str):日志級別,默認和 root logger 對象的級別相同。
  • autoClose (bool):當一些命令執行完之后,是否自動關閉瀏覽器,默認是 True。
  • loop (asyncio.AbstractEventLoop):事件循環對象。

好了,知道這些參數之后,我們可以先試試看。

3.2 無頭模式

首先可以試用下最常用的參數 headless,如果我們將它設置為 True 或者默認不設置它,在啟動的時候我們是看不到任何界面的,如果把它設置為 False,那么在啟動的時候就可以看到界面了,一般我們在調試的時候會把它設置為 False,在生產環境上就可以設置為 True,我們先嘗試一下關閉 headless 模式:

import asyncio
from pyppeteer import launch
async def main():
   await launch(headless=False)
   await asyncio.sleep(100)
asyncio.get_event_loop().run_until_complete(main())

運行之后看不到任何控制台輸出,但是這時候就會出現一個空白的 Chromium 界面了:

 

 

 但是可以看到這就是一個光禿禿的瀏覽器而已,看一下相關信息:

 

 

 看到了,這就是 Chromium,上面還寫了開發者內部版本,你可以認為是開發版的 Chrome 瀏覽器就好。

3.3 調試模式

另外我們還可以開啟調試模式,比如在寫爬蟲的時候會經常需要分析網頁結構還有網絡請求,所以開啟調試工具還是很有必要的,我們可以將 devtools 參數設置為 True,這樣每開啟一個界面就會彈出一個調試窗口,非常方便,示例如下:

import asyncio
from pyppeteer import launch
 
async def main():
   browser = await launch(devtools=True)
   page = await browser.newPage()
   await page.goto('https://www.baidu.com')
   await asyncio.sleep(100)
 
asyncio.get_event_loop().run_until_complete(main())

剛才說過 devtools 這個參數如果設置為了 True,那么 headless 就會被關閉了,界面始終會顯現出來。在這里我們新建了一個頁面,打開了百度,界面運行效果如下:

 

 

 

3.4 禁用提示條

這時候我們可以看到上面的一條提示:“Chrome 正受到自動測試軟件的控制”,這個提示條有點煩,那該怎樣關閉呢?這時候就需要用到 args 參數了,禁用操作如下:

browser = await launch(headless=False, args=['--disable-infobars'])

這里就不再寫完整代碼了,就是在 launch 方法中,args 參數通過 list 形式傳入即可,這里使用的是 --disable-infobars 的參數。

果然還是被檢測到了,頁面如下:

這說明 Pyppeteer 開啟 Chromium 照樣還是能被檢測到 WebDriver 的存在。

那么此時如何規避呢?Pyppeteer 的 Page 對象有一個方法叫作 evaluateOnNewDocument,意思就是在每次加載網頁的時候執行某個語句,所以這里我們可以執行一下將 WebDriver 隱藏的命令,改寫如下:

mport asyncio
from pyppeteer import launch
 
async def main():
   browser = await launch(headless=False, args=['--disable-infobars'])
   page = await browser.newPage()
   await page.evaluateOnNewDocument('Object.defineProperty(navigator, "webdriver", {get: () => undefined})')
   await page.goto('https://antispider1.scrape.cuiqingcai.com/')
   await asyncio.sleep(100)
 
asyncio.get_event_loop().run_until_complete(main())

這里我們可以看到整個頁面就可以成功加載出來了,如圖所示。

 

 

 

我們發現頁面就成功加載出來了,繞過了 WebDriver 的檢測。

3.6 頁面大小設置

在上面的例子中,我們還發現了頁面的顯示 bug,整個瀏覽器窗口比顯示的內容窗口要大,這個是某些頁面會出現的情況。

對於這種情況,我們通過設置窗口大小就可以解決,可以通過 Page 的 setViewport 方法設置,代碼如下:

import asyncio
from pyppeteer import launch
 
width, height = 1366, 768
 
async def main():
   browser = await launch(headless=False, args=['--disable-infobars', f'--window-size={width},{height}'])
   page = await browser.newPage()
   await page.setViewport({'width': width, 'height': height})
   await page.evaluateOnNewDocument('Object.defineProperty(navigator, "webdriver", {get: () => undefined})')
   await page.goto('https://antispider1.scrape.cuiqingcai.com/')
   await asyncio.sleep(100)
 
asyncio.get_event_loop().run_until_complete(main())

這里我們同時設置了瀏覽器窗口的寬高以及顯示區域的寬高,使得二者一致,最后發現顯示就正常了,如圖所示。

3.7 用戶數據持久化

剛才我們可以看到,每次我們打開 Pyppeteer 的時候都是一個新的空白的瀏覽器。而且如果遇到了需要登錄的網頁之后,如果我們這次登錄上了,下一次再啟動又是空白了,又得登錄一次,這的確是一個問題。

比如以淘寶舉例,平時我們逛淘寶的時候,在很多情況下關閉了瀏覽器再打開,淘寶依然還是登錄狀態。這是因為淘寶的一些關鍵 Cookies 已經保存到本地了,下次登錄的時候可以直接讀取並保持登錄狀態。

那么這些信息保存在哪里了呢?其實就是保存在用戶目錄下了,里面不僅包含了瀏覽器的基本配置信息,還有一些 Cache、Cookies 等各種信息都在里面,如果我們能在瀏覽器啟動的時候讀取這些信息,那么啟動的時候就可以恢復一些歷史記錄甚至一些登錄狀態信息了。

這也就解決了一個問題:很多時候你在每次啟動 Selenium 或 Pyppeteer 的時候總是一個全新的瀏覽器,那這究其原因就是沒有設置用戶目錄,如果設置了它,每次打開就不再是一個全新的瀏覽器了,它可以恢復之前的歷史記錄,也可以恢復很多網站的登錄信息。

那么這個怎么來做呢?很簡單,在啟動的時候設置 userDataDir 就好了,示例如下:

import asyncio
from pyppeteer import launch
 
async def main():
   browser = await launch(headless=False, userDataDir='./userdata', args=['--disable-infobars'])
   page = await browser.newPage()
   await page.goto('https://www.taobao.com')
   await asyncio.sleep(100)
 
asyncio.get_event_loop().run_until_complete(main())

好,這里就是加了一個 userDataDir 的屬性,值為 userdata,即當前目錄的 userdata 文件夾。我們可以首先運行一下,然后登錄一次淘寶,這時候我們同時可以觀察到在當前運行目錄下又多了一個 userdata 的文件夾,里面的結構是這樣子的:

具體的介紹可以看官方的一些說明,如: https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md,這里面介紹了 userdatadir 的相關內容。

再次運行上面的代碼,這時候可以發現現在就已經是登錄狀態了,不需要再次登錄了,這樣就成功跳過了登錄的流程。當然可能時間太久了,Cookies 都過期了,那還是需要登錄的。

以上便是 launch 方法及其對應的參數的配置。

3.8 Browser

上面我們了解了 launch 方法,其返回的就是一個 Browser 對象,即瀏覽器對象,我們會通常將其賦值給 browser 變量,其實它就是 Browser 類的一個實例。

下面我們來看看 Browser 類的定義:

class pyppeteer.browser.Browser(connection: pyppeteer.connection.Connection, contextIds: List[str], ignoreHTTPSErrors: bool, setDefaultViewport: bool, process: Optional[subprocess.Popen] = None, closeCallback: Callable[[], Awaitable[None]] = None, **kwargs)

這里我們可以看到其構造方法有很多參數,但其實多數情況下我們直接使用 launch 方法或 connect 方法創建即可。

browser 作為一個對象,其自然有很多用於操作瀏覽器本身的方法,下面我們來選取一些比較有用的介紹下。

3.8.1 開啟無痕模式

我們知道 Chrome 瀏覽器是有一個無痕模式的,它的好處就是環境比較干凈,不與其他的瀏覽器示例共享 Cache、Cookies 等內容,其開啟方式可以通過 createIncognitoBrowserContext 方法,示例如下:

import asyncio
from pyppeteer import launch
 
width, height = 1200, 768
 
async def main():
   browser = await launch(headless=False,
                          args=['--disable-infobars', f'--window-size={width},{height}'])
   context = await browser.createIncognitoBrowserContext()
   page = await context.newPage()
   await page.setViewport({'width': width, 'height': height})
   await page.goto('https://www.baidu.com')
   await asyncio.sleep(100)
 
asyncio.get_event_loop().run_until_complete(main())

這里關鍵的調用就是 createIncognitoBrowserContext 方法,其返回一個 context 對象,然后利用 context 對象我們可以新建選項卡。

運行之后,我們發現瀏覽器就進入了無痕模式,界面如下:

3.8.2 關閉

怎樣關閉自不用多說了,就是 close 方法,但很多時候我們可能忘記了關閉而造成額外開銷,所以要記得在使用完畢之后調用一下 close 方法,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch()
   page = await browser.newPage()
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   await browser.close()

asyncio.get_event_loop().run_until_complete(main())

3.9 Page

Page 即頁面,就對應一個網頁,一個選項卡。在前面我們已經演示了幾個 Page 方法的操作了,這里我們再詳細看下它的一些常用用法。

3.9.1 選擇器

Page 對象內置了一些用於選取節點的選擇器方法,如 J 方法傳入一個選擇器 Selector,則能返回對應匹配的第一個節點,等價於 querySelector。如 JJ 方法則是返回符合 Selector 的列表,類似於 querySelectorAll

下面我們來看下其用法和運行結果,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch()
   page = await browser.newPage()
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   await page.waitForSelector('.item .name')
   j_result1 = await page.J('.item .name')
   j_result2 = await page.querySelector('.item .name')
   jj_result1 = await page.JJ('.item .name')
   jj_result2 = await page.querySelectorAll('.item .name')
   print('J Result1:', j_result1)
   print('J Result2:', j_result2)
   print('JJ Result1:', jj_result1)
   print('JJ Result2:', jj_result2)
   await browser.close()
 
asyncio.get_event_loop().run_until_complete(main())

在這里我們分別調用了 J、querySelector、JJ、querySelectorAll 四個方法,觀察下其運行效果和返回結果的類型,運行結果:

J Result1: <pyppeteer.element_handle.ElementHandle object at 0x1166f7dd0>
J Result2: <pyppeteer.element_handle.ElementHandle object at 0x1166f07d0>
JJ Result1: [<pyppeteer.element_handle.ElementHandle object at 0x11677df50>, <pyppeteer.element_handle.ElementHandle object at 0x1167857d0>, <pyppeteer.element_handle.ElementHandle object at 0x116785110>,
...
<pyppeteer.element_handle.ElementHandle object at 0x11679db10>, <pyppeteer.element_handle.ElementHandle object at 0x11679dbd0>]
JJ Result2: [<pyppeteer.element_handle.ElementHandle object at 0x116794f10>, <pyppeteer.element_handle.ElementHandle object at 0x116794d10>, <pyppeteer.element_handle.ElementHandle object at 0x116794f50>,
...
<pyppeteer.element_handle.ElementHandle object at 0x11679f690>, <pyppeteer.element_handle.ElementHandle object at 0x11679f750>]

在這里我們可以看到,J、querySelector 一樣,返回了單個匹配到的節點,返回類型為 ElementHandle 對象。JJ、querySelectorAll 則返回了節點列表,是 ElementHandle 的列表。

3.9.2 選項卡操作

前面我們已經演示了多次新建選項卡的操作了,也就是 newPage 方法,那新建了之后怎樣獲取和切換呢,下面我們來看一個例子:

import asyncio
from pyppeteer import launch
 
async def main():
   browser = await launch(headless=False)
   page = await browser.newPage()
   await page.goto('https://www.baidu.com')
   page = await browser.newPage()
   await page.goto('https://www.bing.com')
   pages = await browser.pages()
   print('Pages:', pages)
   page1 = pages[1]
   await page1.bringToFront()
   await asyncio.sleep(100) 

在這里我們啟動了 Pyppeteer,然后調用了 newPage 方法新建了兩個選項卡並訪問了兩個網站。那么如果我們要切換選項卡的話,只需要調用 pages 方法即可獲取所有的頁面,然后選一個頁面調用其 bringToFront 方法即可切換到該頁面對應的選項卡。

3.9.3 常見操作

作為一個頁面,我們一定要有對應的方法來控制,如加載、前進、后退、關閉、保存等,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch(headless=False)
   page = await browser.newPage()
   await page.goto('https://dynamic1.scrape.cuiqingcai.com/')
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   # 后退
   await page.goBack()
   # 前進
   await page.goForward()
   # 刷新
   await page.reload()
   # 保存 PDF
   await page.pdf()
   # 截圖
   await page.screenshot()
   # 設置頁面 HTML
   await page.setContent('<h2>Hello World</h2>')
   # 設置 User-Agent
   await page.setUserAgent('Python')
   # 設置 Headers
   await page.setExtraHTTPHeaders(headers={})
   # 關閉
   await page.close()
   await browser.close()

這里我們介紹了一些常用方法,除了一些常用的操作,這里還介紹了設置 User-Agent、Headers 等功能。

3.9.4 點擊

Pyppeteer 同樣可以模擬點擊,調用其 click 方法即可。比如我們這里以 https://dynamic2.scrape.cuiqingcai.com/ 為例,等待節點加載出來之后,模擬右鍵點擊一下,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch(headless=False)
   page = await browser.newPage()
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   await page.waitForSelector('.item .name')
   await page.click('.item .name', options={
       'button': 'right',
       'clickCount': 1,  # 1 or 2
       'delay': 3000,  # 毫秒
   })
   await browser.close()
 
asyncio.get_event_loop().run_until_complete(main())

這里 click 方法第一個參數就是選擇器,即在哪里操作。第二個參數是幾項配置:

  • button:鼠標按鈕,分為 left、middle、right。

  • clickCount:點擊次數,如雙擊、單擊等。

  • delay:延遲點擊。

  • 輸入文本。

對於文本的輸入,Pyppeteer 也不在話下,使用 type 方法即可,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch(headless=False)
   page = await browser.newPage()
   await page.goto('https://www.taobao.com')
   # 后退
   await page.type('#q', 'iPad')
   # 關閉
   await asyncio.sleep(10)
   await browser.close()
 
asyncio.get_event_loop().run_until_complete(main())  

這里我們打開淘寶網,使用 type 方法第一個參數傳入選擇器,第二個參數傳入輸入的內容,Pyppeteer 便可以幫我們完成輸入了。

  • 獲取信息

Page 獲取源代碼用 content 方法即可,Cookies 則可以用 cookies 方法獲取,示例如下:

import asyncio
from pyppeteer import launch
from pyquery import PyQuery as pq
 
async def main():
   browser = await launch(headless=False)
   page = await browser.newPage()
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   print('HTML:', await page.content())
   print('Cookies:', await page.cookies())
   await browser.close()
 
asyncio.get_event_loop().run_until_complete(main())
  • 執行

Pyppeteer 可以支持 JavaScript 執行,使用 evaluate 方法即可,看之前的例子:

import asyncio
from pyppeteer import launch
 
width, height = 1366, 768
 
async def main():
   browser = await launch()
   page = await browser.newPage()
   await page.setViewport({'width': width, 'height': height})
   await page.goto('https://dynamic2.scrape.cuiqingcai.com/')
   await page.waitForSelector('.item .name')
   await asyncio.sleep(2)
   await page.screenshot(path='example.png')
   dimensions = await page.evaluate('''() => {
       return {
           width: document.documentElement.clientWidth,
           height: document.documentElement.clientHeight,
           deviceScaleFactor: window.devicePixelRatio,
       }
   }''')

   print(dimensions)
   await browser.close()
 
asyncio.get_event_loop().run_until_complete(main())

這里我們通過 evaluate 方法執行了 JavaScript,並獲取到了對應的結果。另外其還有 exposeFunction、evaluateOnNewDocument、evaluateHandle 方法可以做了解。

  • 延時等待

在本課時最開頭的地方我們演示了 waitForSelector 的用法,它可以讓頁面等待某些符合條件的節點加載出來再返回。

在這里 waitForSelector 就是傳入一個 CSS 選擇器,如果找到了,立馬返回結果,否則等待直到超時。

除了 waitForSelector 方法,還有很多其他的等待方法,介紹如下。

  • waitForFunction:等待某個 JavaScript 方法執行完畢或返回結果。
  • waitForNavigation:等待頁面跳轉,如果沒加載出來就會報錯。
  • waitForRequest:等待某個特定的請求被發出。
  • waitForResponse:等待某個特定的請求收到了回應。
  • waitFor:通用的等待方法。
  • waitForSelector:等待符合選擇器的節點加載出來。
  • waitForXPath:等待符合 XPath 的節點加載出來。

通過等待條件,我們就可以控制頁面加載的情況了。

4.常規使用

4.1 創建空頁面,並對新的頁面進行調度

#這里launch 里面的參數是一定要填寫的,可避免一些反爬
browser = await launch(headless=False, args=['--disable-infobars'], dumpio=True)
page = await browser.newPage()
await page.goto(url)

4.2 通過選擇器進行操作  

#文本框輸入
def input_time_random():
    return random.randint(150, 351)
#ume --- 具體的值
await page.type(選擇器信息,具體的值,休眠時間)
await page.type(‘#TPL_username_1’, ume, {'delay': input_time_random()})
#點擊
await page.click('#J_SubmitStatic')

4.3 通過xpath 定位/操作

#通過xpath 實現點擊操作
click_handle = await page.xpath("//button[@class='fm-button fm-submit password-login']")
await click_handle[0].click()
#獲取text 文本信息
await item.getProperty("textContent")).jsonValue()

4.4 找到所以iframe 並指定切換

frame_list=page.frames
#通過判斷查找所需
title = await frame[1].title()

4.5 等待上一步頁面加載完,在進行下一步操作

 await asyncio.wait([
    determine_button[0].click(),
      page2.waitForNavigation(),
  ])

4.6 關閉整個頁面

async def page_close(browser):
for _page in await browser.pages():
     await _page.close()
 await browser.close()

4.7 查看獲取到的所有頁面 

#這里可以拿到所有的頁面,通過索引去篩查
page_list = await browser.pages()
await page_list[-1].content() 

5. 更多

另外 Pyppeteer 還有很多功能,如鍵盤事件、鼠標事件、對話框事件等等,在這里就不再一一贅述了。更多的內容可以參考官方文檔的案例說明:https://miyakogi.github.io/pyppeteer/reference.html

以上,我們就通過一些小的案例介紹了 Pyppeteer 的基本用法,下一課時,我們來使用 Pyppeteer 完成一個實戰案例爬取。

本節代碼:https://github.com/Python3WebSpider/PyppeteerTest

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM