使用Pyppeteer抓取渲染網(wǎng)頁

Pyppeteer是Puppeteer的非官方Python支持,Puppeteer是一個無頭JavaScript的基于Chrome/Chromium瀏覽器自動化庫阔涉,可以用于對渲染網(wǎng)頁的抓取。
比較了Pyppeteer和Selenium突照,感覺還是Selenium在函數(shù)的語義上更清晰。

GitHub地址是:https://miyakogi.github.io/pyppeteer

安裝

pip install pyppeteer

用今日頭條練習(xí)一下

import asyncio
from pyppeteer import launch

async def main():
    # headless參數(shù)設(shè)為False怔檩,則變成有頭模式
    browser = await launch(
        # headless=False
    )
    
    page = await browser.newPage()
    
    # 設(shè)置頁面視圖大小
    await page.setViewport(viewport={'width':1280, 'height':800})
    
    # 是否啟用JS,enabled設(shè)為False蓄诽,則無渲染效果
    await page.setJavaScriptEnabled(enabled=True)
    
    await page.goto('https://www.toutiao.com/')
    
    # 打印頁面cookies
    print(await page.cookies())
    
    # 打印頁面文本
    print(await page.content())
    
    # 打印當(dāng)前頁標(biāo)題
    print(await page.title())
    
    # 抓取新聞標(biāo)題
    title_elements = await page.xpath('//div[@class="title-box"]/a')
    for item in title_elements:
        # 獲取文本
        title_str = await (await item.getProperty('textContent')).jsonValue()
        print(await item.getProperty('textContent'))
        # 獲取鏈接
        title_link = await (await item.getProperty('href')).jsonValue()
        print(title_str)
        print(title_link)
    
    # 關(guān)閉瀏覽器
    await browser.close()

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

與百度首頁交互

import time
import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(headless=False)
    page = await browser.newPage()
    await page.setViewport({'width': 1200, 'height': 800})
    await page.goto('https://www.baidu.com')
    # 在搜索框中輸入python
    await page.type('input#kw.s_ipt','python')
    # 點擊搜索按鈕
    await page.click('input#su')
    
    # 等待元素加載薛训,第一種方法,強行等待5秒
    # await asyncio.sleep(5)
    
    # 第二種方法仑氛,在while循環(huán)里強行查詢某元素進行等待
    while not await page.querySelector('.t'):
        pass

    # 滾動到頁面底部
    await page.evaluate('window.scrollBy(0, window.innerHeight)')

    # 這些等待方法都不好用
    # await page.waitForXPath('h3', timeout=300)
    # await page.waitForNavigation(waitUntil="networkidle0")
    # await page.waitForFunction('document.getElementByTag("h3")')
    # await page.waitForSelector('.t')
    # await page.waitFor('document.querySelector("#t")')
    # await page.waitForNavigation(waitUntil='networkidle0')
    # await page.waitForFunction('document.querySelector("").inner??Text.length == 7')

    title_elements = await page.xpath('//h3[contains(@class,"t")]/a')
    for item in title_elements:
        title_str = await (await item.getProperty('textContent')).jsonValue()
        print(title_str)
    await browser.close()

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

官方文檔的兩個示例

# 1 打開一個網(wǎng)頁并做截圖
# 首次運行示例時乙埃,pyppeteer會自動下載對應(yīng)操作系統(tǒng)的chromium
import asyncio
from pyppeteer import launch

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto('http://example.com')
    await page.screenshot({'path': 'example.png'})
    await browser.close()

asyncio.get_event_loop().run_until_complete(main())
# 2 在網(wǎng)頁上執(zhí)行一段腳本
import asyncio
from pyppeteer import launch

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto('http://example.com')
    await page.screenshot({'path': 'example.png'})

    dimensions = await page.evaluate('''() => {
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight,
            deviceScaleFactor: window.devicePixelRatio,
        }
    }''')

    print(dimensions)
    # >>> {'width': 800, 'height': 600, 'deviceScaleFactor': 1}
    await browser.close()

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

Pyppeteer和Puppeteer的不同點

  1. Pyppeteer支持字典和關(guān)鍵字傳參,Puppeteer只支持字典傳參
# Puppeteer只支持字典傳參
browser = await launch({'headless': True})
# Pyppeteer支持字典和關(guān)鍵字傳參
browser = await launch({'headless': True})
browser = await launch(headless=True)
  1. 元素選擇器方法名 $變?yōu)閝uerySelector
# Puppeteer使用$符
Page.$()/Page.$$()/Page.$x()
# Pyppeteer使用Python風(fēng)格的函數(shù)名
Page.querySelector()/Page.querySelectorAll()/Page.xpath()
# 簡寫方式為:
Page.J(), Page.JJ(), and Page.Jx()
  1. Page.evaluate() 和 Page.querySelectorEval()的參數(shù)

Puppeteer的evaluate()方法使用JavaScript原生函數(shù)或JavaScript表達(dá)式字符串锯岖。Pyppeteer的evaluate()方法只使用JavaScript字符串介袜,該字符串可以是函數(shù)也可以是表達(dá)式,Pyppeteer會進行自動判斷出吹。但有時會判斷錯誤遇伞,如果字符串被判斷成了函數(shù),并且報錯捶牢,可以添加選項force_expr=True鸠珠,強制Pyppeteer作為表達(dá)式處理。

獲取頁面內(nèi)容:

content = await page.evaluate('document.body.textContent', force_expr=True)

獲取元素的內(nèi)部文字:

element = await page.querySelector('h1')
title = await page.evaluate('(element) => element.textContent', element)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秋麸,一起剝皮案震驚了整個濱河市渐排,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灸蟆,老刑警劉巖驯耻,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異次乓,居然都是意外死亡吓歇,警方通過查閱死者的電腦和手機孽水,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門票腰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人女气,你說我怎么就攤上這事杏慰。” “怎么了炼鞠?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵缘滥,是天一觀的道長。 經(jīng)常有香客問我谒主,道長朝扼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任霎肯,我火速辦了婚禮擎颖,結(jié)果婚禮上榛斯,老公的妹妹穿的比我還像新娘。我一直安慰自己搂捧,他們只是感情好驮俗,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著允跑,像睡著了一般王凑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聋丝,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天索烹,我揣著相機與錄音,去河邊找鬼潮针。 笑死术荤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的每篷。 我是一名探鬼主播瓣戚,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼焦读!你這毒婦竟也來了子库?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矗晃,失蹤者是張志新(化名)和其女友劉穎仑嗅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體张症,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡仓技,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俗他。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脖捻。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兆衅,靈堂內(nèi)的尸體忽然破棺而出地沮,到底是詐尸還是另有隱情,我是刑警寧澤羡亩,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布摩疑,位于F島的核電站,受9級特大地震影響畏铆,放射性物質(zhì)發(fā)生泄漏雷袋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一辞居、第九天 我趴在偏房一處隱蔽的房頂上張望楷怒。 院中可真熱鬧寨腔,春花似錦、人聲如沸率寡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冶共。三九已至乾蛤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捅僵,已是汗流浹背家卖。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庙楚,地道東北人上荡。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像馒闷,于是被迫代替她去往敵國和親酪捡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 一纳账、快捷鍵 ctr+b 執(zhí)行ctr+/ 單行注釋ctr+c ...
    o_8319閱讀 5,828評論 2 16
  • 一逛薇、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 5,748評論 0 10
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章疏虫,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,767評論 2 9
  • 焦點網(wǎng)絡(luò)九期中級紫分享第266天 本周約練第一次 今天是周二永罚,上午看到群里有九點的約練,當(dāng)時正準(zhǔn)備去備午飯的食材卧秘,...
    紫smile閱讀 163評論 0 0
  • 你還在單身的原因是什么呢袱? 總有一個戳中你
    Dz咕咕叫閱讀 138評論 0 0