久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Pyppeteer爬蟲神器詳解

 東西二王 2023-01-17 發(fā)布于重慶
原創(chuàng)2020-07-05 07:22·全棧集結(jié)號

這是接上一篇文章超越selenium的爬蟲神器Pyppeteer,墻裂建議沒有看過的同學花兩分鐘了解一下它的簡單使用,。

launch

使用Pyppeteer的第一步就是啟動瀏覽器,,就是相當于我們點擊桌面上的瀏覽器圖標一樣,把它運行起來,。用Pyppeteer完成同樣的操作,,只需要調(diào)用launch方法就行了。

先看一下launch方法的API定義:

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

從官方文檔和定義當中我們可以看到它處于launcher模塊中,,返回一個Brower對象,,從源碼中可以看出這個方法是通過async修飾的,所以調(diào)用的時候需要使用await,。

下面我們看看它的參數(shù):

  • ignoreHTTPSErrors(bool):是否要忽略HTTPS的錯誤,,默認是False。

  • headless(bool):是否啟用Headless模式,,即無界面模式,,如果devtools這個參數(shù)是True,那么該參數(shù)就會被設(shè)置為False,,否則為True,,默認是開啟無界面模式。

  • executablePath(str):可執(zhí)行文件的路徑,,如果指定之后就不需要使用默認的Chromium了,,可以指定為已有的Chrome或者Chromium。

  • slowMo(int|float):通過傳入指定的時間,,可以減緩Pyppeteer的一些模擬操作,。

  • args(List[str]):在執(zhí)行過程中可以傳入的額外參數(shù),。

  • ignoreDefaultArgs(bool):不使用Pyppeteer的默認參數(shù),如果使用了這個參數(shù),,最好通過args參數(shù)來設(shè)定一些參數(shù),,否則可能會出現(xiàn)一些意想不到的問題。慎用此參數(shù),。

  • handleSIGINT(bool):是否享有SIGINT信號,,也就是用Ctrl+C來關(guān)閉瀏覽器,默認是True,。

  • handleSIGTERM(bool):是否享有SIGTERM信號,,一般是kill命令,默認為True,。

  • handleSIGHUP (bool):是否響應SIGHUP信號,,即掛起信號,比如終端退出操作,,默認是 True,。

  • dumpio (bool):是否將 Pyppeteer 的輸出內(nèi)容傳給 process.stdout 和 process.stderr 對象,默認是 False,。

  • userDataDir (str):即用戶數(shù)據(jù)文件夾,,即可以保留一些個性化配置和操作記錄。

  • env (dict):環(huán)境變量,,可以通過字典形式傳入,。

  • devtools (bool):是否為每一個頁面自動開啟調(diào)試工具,默認是 False,。如果這個參數(shù)設(shè)置為 True,,那么 headless 參數(shù)就會無效,會被強制設(shè)置為 False,。

  • logLevel (int|str):日志級別,,默認和 root logger 對象的級別相同。

  • autoClose (bool):當一些命令執(zhí)行完之后,,是否自動關(guān)閉瀏覽器,,默認是 True。

  • loop (asyncio.AbstractEventLoop):事件循環(huán)對象,。

了解了這些參數(shù),,我們可以試一些常用的參數(shù)。

  • 無頭模式

一般情況下我們都使用的是無頭模式,,將參數(shù)headless設(shè)置為True或者不設(shè)置它,這個時候我們是看不到任何界面的,。一般我們都使用無頭模式進行運行調(diào)試,,那么我們可以嘗試關(guān)閉headless模式看看效果:

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

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

這個時候我們看到在任務(wù)欄中顯示了一個藍色Chrome圖標。

  • 調(diào)試模式

我們在寫爬蟲的時候,,經(jīng)常需要分析網(wǎng)頁結(jié)構(gòu)和網(wǎng)絡(luò)請求,,所以打開調(diào)試工具是很有必要的,將devtools參數(shù)設(shè)置為True,,這樣每開啟一個就彈出一個調(diào)試窗口

import asynciofrom pyppeteer import launchasync 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這個參數(shù)設(shè)置為True,,那么headless就不起作用了,界面始終會顯示出來,。

  • 禁用提示條

使用Pyppeteer操作網(wǎng)頁的時候,,我們可以看到上面的一條提示:"Chrome 正受到自動測試軟件的控制",這個提示條有點煩,,那該怎樣關(guān)閉呢,?這時候就需要用到 args 參數(shù)了,禁用操作如下:

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

  • 防止檢測

現(xiàn)在很多網(wǎng)站的反爬已經(jīng)可以檢測自動化操作瀏覽器的爬蟲了,,主要就是檢測webdriver,,因為我們使用的是selenium+webdriver的方式去驅(qū)動瀏覽器,所以都會留下webdriver的痕跡,,會被平臺識別,。那么如何規(guī)避呢?就要通過將webdriver隱藏來達到防止檢測的目的,。Pyppeteer為我們提供了一個方法叫做evaluateOnnewDocument,,意思就是在每次加載頁面的時候執(zhí)行某個語句,所以我們可以在這里執(zhí)行以下隱藏webdriver的命令,。

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://movie.douban.com/chart')    await asyncio.sleep(100)
  • 頁面大小設(shè)置

在之前的顯示窗口中,,我們會發(fā)現(xiàn)窗口顯示并不完全,在某些頁面會出現(xiàn)BUG,,因此我們應該盡量保證窗口完全顯示,。這個時候就用到了設(shè)置窗口大小的方法,通過Page對象的setViewport方法設(shè)置就可以了,。

async def main():
    width = 1366
    height = 768
    browser = await launch(headless=False, args=['--disable-infobars'])
    page = await browser.newPage()    await page.setViewport({'width': width, 'height': height})    await page.goto('https://movie.douban.com/chart')    await asyncio.sleep(100)
  • 用戶數(shù)據(jù)持久化

通過前面的例子,,我們發(fā)現(xiàn)一個問題,每次使用Pyppeteer打開瀏覽器的時候都是一個空白頁,,這樣會有什么問題呢,?如果遇到一個需要登錄的網(wǎng)頁,這次我們登錄了,,下一次啟動又得登錄一次,,這就是一個問題。

比如淘寶,,平時我們?yōu)g覽完淘寶后,,關(guān)閉瀏覽器再打開,,依然還是登錄狀態(tài)。大家都知道,,這是因為瀏覽器本地保存了Cookies的緣故,,下次打開可以直接讀取并保持登錄狀態(tài)。這些信息一般保存在我們的用戶目錄下,,如果我們能在瀏覽器啟動的時候讀取這些信息,,那么啟動的時候就可以恢復一些歷史記錄甚至是登錄狀態(tài)信息了。

我們在使用Selenium或者Pyppeteer的時候,,每次打開都是一個全新的瀏覽器,,原因就是我們沒有設(shè)置用戶目錄,如果設(shè)置了,,那就可以讀取一些信息在啟動的時候加載上來,。Pyppeteer為我們提供了一個userDataDir參數(shù)來設(shè)置用戶目錄,這樣就可以保持我們的訪問狀態(tài)了,。

async def main():
    width = 1366
    height = 768
    browser = await launch(headless=False, userDataDir='userdata', args=['--disable-infobars'])
    page = await browser.newPage()    await page.setViewport({'width': width, 'height': height})    await page.goto('https://mp.weixin.qq.com/')    await asyncio.sleep(100)

這里我們用微信公眾號進行測試,,首先運行一下,登陸一次公眾號,,然后我們可以打開當前目錄下生成的userdata文件夾,,里面內(nèi)容如下:

在此運行一下上面的代碼,就直接進入我們的公眾號管理界面,,已經(jīng)是登錄狀態(tài)了,,就跳過了登錄的流程。當然了,,我們知道Cookies基本都是有期限的,,如果過期了就需要再次登錄。

Browser

上面我們介紹了launch方法,,它會返回一個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)

我們看到這個類的初始化參數(shù)有很多,但是我們上面基本上都是使用launch方法直接創(chuàng)建使用,。但是Browser類還是用于很多操作瀏覽器本身的方法,,下面我們來介紹一些常用的。

  • 開啟無痕模式

Chrome瀏覽器本身是有一個無痕模式的,,它的好處就是干凈,,不加載Cache、Cookies等內(nèi)容,,可以通過方法
createIncogniteBrowserContext來開啟:

async def main():
    width = 1366
    height = 768
    browser = await launch(headless=False, args=['--disable-infobars', f'--window-size={width}, {height}'])
    context = await browser.createIncogniteBrowserContext()
    page = await context.newPage()    await page.setViewport({'width': width, 'height': height})    await page.goto('https://mp.weixin.qq.com/')    await asyncio.sleep(100)

這里我們還使用了一個新的參數(shù)設(shè)置--window-size,,這個是用來設(shè)置瀏覽器的窗口大小,與下面的setViewport相比,,一個是設(shè)置窗口大小,,一個是設(shè)置頁面大小,。我們這里調(diào)用了
createIncogniteBrowserContext方法,,返回了一個context對象,,然后用這個對象打開網(wǎng)頁,就進入了無痕模式,。

在執(zhí)行這段代碼的時候,,我先執(zhí)行了一次上面那一次代碼,發(fā)現(xiàn)依然是處于登錄狀態(tài),,然后我們執(zhí)行本次代碼后發(fā)現(xiàn)顯示如下:

發(fā)現(xiàn)出現(xiàn)了兩層窗口,,一個是launch創(chuàng)建的browser窗口,一個是通過
createIncogniteBrowserContext創(chuàng)建的無痕窗口,。

  • 關(guān)閉

很多時候我們忘記關(guān)閉瀏覽器,,就會導致它一直存在內(nèi)存中。如果是可視模式下,,我們還能從任務(wù)欄看到它,,但是在后臺模式下,我們只能在任務(wù)管理器里去找它,,這時候就很容易被忽略掉,。所以一定要記住,使用完畢調(diào)用一下close方法:

async def main():
    width = 1366
    height = 768
    browser = await launch(headless=False, args=['--disable-infobars', f'--window-size={width}, {height}'])
    context = await browser.createIncogniteBrowserContext()
    page = await context.newPage()    await page.setViewport({'width': width, 'height': height})    await page.goto('https://mp.weixin.qq.com/')    await asyncio.sleep(100)    await browser.close()

Page

Page就是頁面,,每一個選項卡就是一個頁面,,它的類定義如下:

class pyppeteer.page.Page(client: pyppeteer.connection.CDPSession, target: Target, frameTree: Dict[KT, VT], ignoreHTTPSErrors: bool, screenshotTaskQueue: list = None)

我們上面在使用的過程中都是通過browser對象創(chuàng)建一個新頁面,這也是我們經(jīng)常使用它的方式,,接下來我們看一下它的常用方法,。

  • 選擇器

Page對象內(nèi)置了一些用于選取節(jié)點的選擇器方法,比如J方法傳入一個選擇器Selector,,則能返回對應匹配的第一個節(jié)點,,相當于querySelector。JJ方法則是返回符合Selector的列表,,相當于querySelectorAll,。

下面我們就來看看它的用法:

async def main():
    browser = await launch()
    page = await browser.newPage()    await page.goto('https://movie.douban.com/chart')    await page.waitForSelector('table .item')
    j1 = await page.J('table .item')
    j2 = await page.querySelector('table .item')
    jj1 = await page.JJ('table .item')
    jj2 = await page.querySelectorAll('table .item')
    print('J Result: ', j1)
    print('querySelector Result: ', j2)
    print('JJ Result: ', jj1)
    print('querySelectorAll Result: ', jj2)    await browser.close()

我們分別使用J、JJ,、querySelector,、querySelectorAll四個方法,看一下他們的輸出結(jié)果:

J Result:  <pyppeteer.element_handle.ElementHandle object at 0x1147734d0>
querySelector Result:  <pyppeteer.element_handle.ElementHandle object at 0x114788c50>
JJ Result:  [<pyppeteer.element_handle.ElementHandle object at 0x1147324d0>, <pyppeteer.element_handle.ElementHandle object at 0x114732a50>, <pyppeteer.element_handle.ElementHandle object at 0x11472aa90>, <pyppeteer.element_handle.ElementHandle object at 0x11472a110>, <pyppeteer.element_handle.ElementHandle object at 0x11472a0d0>, <pyppeteer.element_handle.ElementHandle object at 0x11478d210>, <pyppeteer.element_handle.ElementHandle object at 0x11478d290>, <pyppeteer.element_handle.ElementHandle object at 0x11478d2d0>, <pyppeteer.element_handle.ElementHandle object at 0x11478d250>, <pyppeteer.element_handle.ElementHandle object at 0x11478d310>]
querySelectorAll Result:  [<pyppeteer.element_handle.ElementHandle object at 0x114786690>, <pyppeteer.element_handle.ElementHandle object at 0x114786750>, <pyppeteer.element_handle.ElementHandle object at 0x114781610>, <pyppeteer.element_handle.ElementHandle object at 0x114781fd0>, <pyppeteer.element_handle.ElementHandle object at 0x114781b10>, <pyppeteer.element_handle.ElementHandle object at 0x11478dd50>, <pyppeteer.element_handle.ElementHandle object at 0x11478ddd0>, <pyppeteer.element_handle.ElementHandle object at 0x11478de10>, <pyppeteer.element_handle.ElementHandle object at 0x11478dd90>, <pyppeteer.element_handle.ElementHandle object at 0x11478de50>]

從結(jié)果中可以看出來,,J和querySelector返回單個對象,,JJ和querySelectorAll返回多個對象

  • 選項卡操作

前面我們說過,Page對象就是一個選項卡,,我們均使用newPage方法創(chuàng)建了,,那么新建之后怎么獲取和切換呢,,下面看一個例子:

async def main():
    browser = await launch(headless=False, args=['--disable-infobars'])
    page = await browser.newPage()    await page.goto('https://mp.weixin.qq.com/')
    page = await browser.newPage()    await page.goto('https://www.baidu.com')
    pages = await browser.pages()
    print('Pages: ', pages)
    page1 = pages[1]    await page1.bringToFront()    await asyncio.sleep(20)    await browser.close()

我們在這里調(diào)用了兩次newPage,訪問了兩個網(wǎng)站,,當切換選項卡的時候,,我們只要用對應頁面的page對象調(diào)用其bringToFront方法即可。

  • 常見操作

下面我們再看一些頁面的常用操作:加載,、前進,、后退、關(guān)閉,、保存

async def main():
    browser = await launch(headless=False, args=['--disable-infobars'])
    page = await browser.newPage()    await page.goto('https://www.baidu.com')    await page.goto('https://pan.baidu.com')    # 后退
    await page.goBack()    # 前進
    await page.goForward()    #保存PDF
    await page.pdf(path='test.pdf')    #截圖
    await page.screenshot()    # 設(shè)置頁面
    await page.setContent('<h1>Hello World</h1>')    # 設(shè)置User-Agent
    await page.setUserAgent('Python')    # 設(shè)置Headers
    await page.setExtraHTTPHeaders(headers={})    # 關(guān)閉
    await page.close()    await browser.close()

這里有一個PDF保存真的非常方便,,我之前用selenium保存網(wǎng)頁成PDF,找了很多處理方式,,還比較麻煩,,Pyppeteer這里就調(diào)用一個函數(shù)就OK了,但是要注意兩點,,否則保存不成功:1. 必須使用無頭模式,。2.要指定保存路徑path,否則不會保存在本地,。

  • 輸入并點擊

模擬鼠標點擊和鍵盤輸入事件,。

async def main():
    browser = await launch(headless=False)
    page = await browser.newPage()    await page.goto('https://www.baidu.com')    await page.waitForSelector('#su')    await page.type('#kw', 'python')    await page.click('#su', options={        'button': 'left',        'clickCount': 1,        'delay': 300
    })    await asyncio.sleep(10)    await browser.close()

click就是點擊事件,第一個參數(shù)是選擇器,,第二個參數(shù)是幾項配置:

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

clickCount: 點擊類型,,如雙擊、單擊

delay:延遲點擊

type方法為輸入方法,,第一個參數(shù)傳入選擇器,,第二個參數(shù)傳入內(nèi)容。

  • 獲取網(wǎng)頁源碼和cookies

content = await page.content()cookies = await page.cookies()
  • 執(zhí)行js腳本

out_content = await page.evaluate('''() => {
                                  return {
                                          width: document.documentElement.clientWidth,
                                          height: document.documentElement.clientHeight,
                                          deviceScaleFactor: window.devicePixelRatio
                                      }
                                  }''')
  • 延時等待

這個部分相比于selenium又方便了很多,,可以讓頁面等待符合某些條件后,,再向下執(zhí)行,這在我們等待頁面加載是非常有用,,除了我們之前使用過的waitForXPath,、waitForSelector還有以下幾個:

waitForFunction:等待某個JavaScript方法執(zhí)行完畢或返回結(jié)果

waitForNavigation:等待頁面跳轉(zhuǎn),如果沒加載出來就會報錯

waitForRequest:等待某個特定請求被發(fā)出

waitForResponse:等待某個特定請求收到了回應

waitFor:通用的等待方法

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

除了以上我們介紹的東西,還有鼠標模擬拖動也是比較重要的,這在模擬滑動驗證碼的時候是非常有用的,,我們后面再開一篇吧,。

搜更多精彩內(nèi)容

Pyppeteer詳解

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約