Python 異步自動化測試工具 pyppeteer

pyppeteer

提起 selenium 想必大家都不陌生,作為一款知名的 Web 自動化測試框架,selenium 支持多款主流瀏覽器,提供了功能豐富的API 接口,經(jīng)常被我們用作爬蟲工具來使用。但是 selenium 的缺點(diǎn)也很明顯,比如速度太慢、對版本配置要求嚴(yán)苛柔袁,最麻煩是經(jīng)常要更新對應(yīng)的驅(qū)動腥例。還有些網(wǎng)頁是可以檢測到是否是使用了selenium 构回。并且selenium 所謂的保護(hù)機(jī)制不允許跨域 cookies 保存以及登錄的時(shí)候必須先打開網(wǎng)頁然后后加載 cookies 再刷新的方式很不友好政己。那么pyppeteer便成為你的不二之選。

安裝

pip install pypeteer 
pip install asyncio

pypeteer 常見操作

  • 啟動瀏覽器實(shí)例
browser = await launch()
  • 打開一個空白頁
page = await browser.newPage()
  • 在地址欄輸入網(wǎng)址并等待加載
await page.goto('https://example.com')
  • 網(wǎng)頁截圖
await page.screenshot({path: 'example.png'})
  • 添加useragent
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299')
  • 打開百度
await page.goto('https://www.baidu.com')
  • 獲取輸入框焦點(diǎn)并輸入文字
await page.type('#kw', keyword, {'delay': 100}) 獲取輸入框焦點(diǎn)并輸入文字{'delay': input_time_random() - 50}
  • 鼠標(biāo)點(diǎn)擊
# await page.click() 點(diǎn)擊一個元素
await page.click('#su')
  • 等待頁面加載出來
await page.waitForNavigation({'waitUntil': 'load'})
# 等待頁面加載出來欠气,等同于window.onload
  • 關(guān)掉瀏覽器
await browser.close()
  • 獲取網(wǎng)頁內(nèi)容
content = await page.content()
  • 獲取cookies
await get_cookie(page)
cookies = await page.cookies()
  • 在網(wǎng)頁中執(zhí)行js代碼
await page.evaluate(js1)
  • 模擬鍵盤按下某個按鍵
await page.keyboard.press 
  • 頁面等待宜鸯,可以是時(shí)間淋袖、某個元素焰情、某個函數(shù)
await page.waitFor(10000)
  • 獲得當(dāng)前訪問的url
await page.url 
  • 獲取當(dāng)前頁面所有的 iframe裸准,然后根據(jù) iframe 的名字精確獲取某個想要的 iframe
await page.frames() 
  • 獲取 iframe 中的某個元素
await iframe.$('.srchsongst') 
  • 在瀏覽器中執(zhí)行函數(shù)炒俱,相當(dāng)于在控制臺中執(zhí)行函數(shù),返回一個 Promise
await iframe.evaluate() 
  • 將類數(shù)組對象轉(zhuǎn)化為對象
Array.from 
  • 相當(dāng)于在 iframe 中運(yùn)行 document.queryselector 獲取指定元素推盛,并將其作為第一個參數(shù)傳遞
await iframe.$eval() 
  • 相當(dāng)于在 iframe 中運(yùn)行 document.querySelectorAll 獲取指定元素?cái)?shù)組峦阁,并將其作為第一個參數(shù)傳遞
await iframe.$$eval 
  • 設(shè)置頁面大小
await self.page.setViewport(viewport={'width': width, 'height': height})

代碼演示

from pyppeteer import launch
import asyncio
import copy


class TestSpider(object):
    def __init__(self):
        self.chrome_extension = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
        self.launch_kwargs = {
          # 控制是否為無頭模式
        'executablePath': chrome_extension,  # chrome 文件目錄位置
        "headless": True,  # 控制是否為無頭模式
        "dumpio": True,  # 當(dāng)界面開多了時(shí)會卡住,設(shè)置這個參數(shù)就不會了
        "userDataDir": r"./ceshi",  # 用戶數(shù)據(jù)保存目錄 這個最好也自己指定一個目錄
        # 如果不指定的話耘成,chrome會自動新建一個臨時(shí)目錄使用榔昔,在瀏覽器退出的時(shí)候會自動刪除臨時(shí)目錄
        # 在刪除的時(shí)候可能會刪除失敗(不知道為什么會出現(xiàn)權(quán)限問題瘪菌,我用的windows) 導(dǎo)致瀏覽器退出失敗
        # 然后chrome進(jìn)程就會一直沒有退出 CPU就會狂飆到99%
        'autoClose': True,
        # chrome啟動命令行參數(shù)
        "args": [
            # 瀏覽器代理 配合某些中間人代理使用
            # "--proxy-server=http://127.0.0.1:8008",
            # 最大化窗口
            "--start-maximized",
            # 窗口大小
            '--window-size=1366,768'撒会,
            # 取消沙盒模式 沙盒模式下權(quán)限太小
            "--no-sandbox",
            # 不顯示信息欄  比如 chrome正在受到自動測試軟件的控制 ...
            "--disable-infobars",
            # log等級設(shè)置 在某些不是那么完整的系統(tǒng)里 如果使用默認(rèn)的日志等級 可能會出現(xiàn)一大堆的warning信息
            "--log-level=3",
            # 設(shè)置UA
            "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
        ],

    }

    def __del__(self):
        asyncio.gather(self.browser.close())  # 爬蟲程序結(jié)束,關(guān)閉 browser對象
        print("-------程序結(jié)束")

    async def run(self): 
        item = dict()
        url_list = ["http://www.reibang.com/u/93d4bac0fa23"]  # 此處鏈接脫敏處理
        temp_url = "http://www.reibang.com/u/93d4bac0fa23/{}.html" # 此處鏈接脫敏處理
        for i in range(2, 10):
            url_list.append(temp_url.format(i))
        self.browser = await launch(self.launch_kwargs)
        page = await self.browser.newPage()
        await page.evaluateOnNewDocument(
            '() =>{ Object.defineProperties(navigator,''{ webdriver:{ get: () => false } }) }')
        await page.setUserAgent(
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36')
        for url in url_list:
            await page.goto(url, waitUntil='networkidle0')  # 等待網(wǎng)頁加載完成
            item_list = []
            item["detail_url"] = url
            a_list = await page.xpath("http://ul[@class='list']//li/a")  # 利用xpath語法提取數(shù)據(jù)
            for i in a_list:
                title = await (await i.getProperty("textContent")).jsonValue()  # 提取文本內(nèi)容
                get_url = await (await i.getProperty("href")).jsonValue() 
                item["title"], item["get_url"] = str(title).strip(), get_url
                item_list.append(copy.deepcopy(item))
            if item_list:
                await self.get_detail_parse(page, copy.deepcopy(item_list))

    async def get_detail_parse(self, page, item_list):
        for item in item_list:
            await page.goto(item["get_url"], waitUntil='networkidle0')  # 等待網(wǎng)頁加載完成
            a_list = await page.xpath("http://div[@class='content']//a")
            content_data = await page.content()
            print(content_data)
            for i in a_list:
                item["name"] = await (await i.getProperty("textContent")).jsonValue()
                item["url"] = await (await i.getProperty("href")).jsonValue()
                print(item)


if __name__ == '__main__':
    func = TestSpider()
    asyncio.run(func.run())  # 運(yùn)行協(xié)程程序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載师妙,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者诵肛。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市默穴,隨后出現(xiàn)的幾起案子怔檩,更是在濱河造成了極大的恐慌,老刑警劉巖壁顶,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珠洗,死亡現(xiàn)場離奇詭異,居然都是意外死亡若专,警方通過查閱死者的電腦和手機(jī)许蓖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來调衰,“玉大人膊爪,你說我怎么就攤上這事『坷颍” “怎么了米酬?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趋箩。 經(jīng)常有香客問我赃额,道長加派,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任跳芳,我火速辦了婚禮芍锦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘飞盆。我一直安慰自己媒咳,他們只是感情好嵌削,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布颓鲜。 她就那樣靜靜地躺著尊浪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪城看。 梳的紋絲不亂的頭發(fā)上女气,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機(jī)與錄音析命,去河邊找鬼主卫。 笑死,一個胖子當(dāng)著我的面吹牛鹃愤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播完域,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼软吐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吟税?” 一聲冷哼從身側(cè)響起凹耙,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肠仪,沒想到半個月后肖抱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡异旧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年意述,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吮蛹。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡荤崇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潮针,到底是詐尸還是另有隱情术荤,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布每篷,位于F島的核電站瓣戚,受9級特大地震影響端圈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜子库,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一枫笛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刚照,春花似錦刑巧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浑彰,卻和暖如春恭理,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背郭变。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工颜价, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诉濒。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓周伦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親未荒。 傳聞我的和親對象是個殘疾皇子专挪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

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