日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Pyppeteer库之四:Pyppeteer的页面操作(下)

發(fā)布時間:2024/1/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Pyppeteer库之四:Pyppeteer的页面操作(下) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

執(zhí)行自定義的JS腳本

Pyppeteer Page對象提供了一系列evaluate方法,你可以通過他們來執(zhí)行一些自定義JS代碼,主要提供了下面三個API:

(1) page.evaluate(pageFunction [,...args]), 返回pageFunction執(zhí)行的結(jié)果,pageFunction表示要在頁面執(zhí)行的函數(shù)或表達(dá)式,args表示傳入給pageFunction的參數(shù)

示例:

await page.goto('https://www.baidu.com') # 輸出字符串 await page.evaluate('alert("在瀏覽器執(zhí)行js腳本!")') # 將元素作為參數(shù)傳入 page.evaluate element = await page.J('#ul>a[name="tj_trtieba"]') print(await page.evaluate('el => el.innerHTML', element)) print(await page.evaluate('el => el.href', element) # 執(zhí)行函數(shù) el = await page.evaluate('() => document.querySelector("#su").value') print(el)

(2) page.evaluateHandle(pageFunction[,...args]), 此方法和page.evaluate的唯一區(qū)別是此方法返回的是頁內(nèi)類型(JSHandle)

示例:

await page.goto('https://www.baidu.com') el = await page.evaluateHandle('() => document.querySelector("#su").value') print(type(el)) print(el.toString())

(3) page.evaluateOnNewDocument(pageFunction[, ...args]), 指定的函數(shù)在所屬的頁面被創(chuàng)建并且所屬頁面的任意script執(zhí)行之前被調(diào)用。常用于修改頁面JS環(huán)境。

以下為插入中間JS,將淘寶會為了檢測瀏覽器而調(diào)用的JS修改其結(jié)果:

import asyncio from pyppeteer import launchasync def main():browser = await launch({'headless': False,'args': ['--no-sandbox', '--window-size=1366,768']})page = await browser.newPage()await page.setViewPort({'width': 1366, 'height': 768})await page.evaluateOnNewDocument('''() => {Object.defineProperty(navigator, 'webdriver', {get: () => false });}''')await page.goto('https://login.taobao.com')await page.evaluate('alert(navigator.webdriver)')await browser.close()asyncio.get_event_loop().run_until_complete(main())

元素操作

ElementHandle表示頁內(nèi)的DOM元素,你可以通過page.querySelector()方法創(chuàng)建。DOM元素具有和page相同的某些方法: J()、JJ()、Jeval()、JJeval()、screenshot()、type()、click()、tap()。此外,還有一些好用的方法:

(1) 獲取元素邊界框坐標(biāo): boundingBox(),返回元素的邊界框(相對于主框架) => x坐標(biāo)、y坐標(biāo)、width、height

(2) 元素是否可見: isIntersectingViewport()

(3) 上傳文件: uploadFile(*filepaths)

(4) ElementHandle類轉(zhuǎn)Frame類:contentFrame(),如果句柄未引用iframe,則返回None。

(5) 聚焦該元素: focus()

(6) 與鼠標(biāo)相關(guān): hover(),將鼠標(biāo)懸停到元素上面

(7) 與鍵盤相關(guān): press(key[, options]),按鍵,key表示按鍵的名稱,options可配置:

  • text(string) - 如果指定,則使用此文本生成輸入事件
  • delay(number) - keydown和keyup之間等待的時間,默認(rèn)是0

?

鼠標(biāo)事件

Mouse 類在相對于視口左上角的主框架CSS像素中運(yùn)行。

(1) page.mouse.down([options]) 按下鼠標(biāo),options 可配置:

  • button(str) 按下了哪個鍵,可選值為[left, right, middle],默認(rèn)是left,表示鼠標(biāo)左鍵
  • clickCount(int) 按下的次數(shù),單擊,雙擊或者其他次數(shù)

(2) page.mouse.up([options])松開鼠標(biāo),options同上

(3) page.mouse.move(x, y, [options])移動鼠標(biāo)到指定位置,options.steps表示移動的步長

(4) page.mouse.click(x, y, [options])鼠標(biāo)點(diǎn)擊指定的位置,其實(shí)是mouse.move和mouse.down或mouse.up的快捷操作

?

模擬登錄的驗(yàn)證碼處理

可能用到的方法:

  • ElementHandle.boundingBox()、ElementHandle.hover()
  • mouse.down()、mouse.move()、mouse.up()、mouse.click()

實(shí)例一:淘寶驗(yàn)證碼 拖動滑塊

(1) 淘寶的驗(yàn)證碼驗(yàn)證模塊會檢測瀏覽器環(huán)境,要注入JS;

(2) 盡可能模擬用戶操作,隨機(jī)數(shù)減慢Pyppeteer的執(zhí)行速度;

示例:

import asyncio import random from pyppeteer import launchasync def main():browser = await launch({'headless': False,'args': ['--no-sandbox', '--window-size=1366,768']})page = await browser.newPage()await page.setViewport({'width': 1366, 'height': 768})await page.evaluateOnNewDocument('''() => {Object.defineProperties(navigator, { webdriver:{ get: () => false}}}''')await page.evaluateOnNewDocument('''() => {window.navigator.chrome = { runtime: {}, };}''')await page.evaluateOnNewDocument('''() => {Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] });}''')await page.evaluateOnNewDocument('''() => {Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')await page.goto('https://login.taobao.com')await asyncio.sleep(2)try:await page.click('div.login-links > a.forget-pwd.J_Quick2Static')except:passawait asyncio.sleep(2)await page.type('#TPL_username_1', '123123123', {'delay': random.randint(60, 121)})await page.type('#TPL_password_1', '1234567890', {'delay': random.randint(100, 151)})await asyncio.sleep(1.5)try:el = await page.querySelector('#nc_1_n1z')box = await el.boundingBox()await page.hover('#nc_1_n1z')await page.mouse.down()await page.mouse.move(box['x'] + random.randint(333, 999), box['y'], {'steps': 5})await page.mouse.up()except:passawait asyncio.sleep(1.8)await page.click('#J_SubmitStatic')await asyncio.sleep(5)await browser.close()asyncio.get_event_loop().run_until_complete(main())

實(shí)例二:鐵路12306點(diǎn)觸驗(yàn)證碼

(1) 分析12306的驗(yàn)證碼;這個東西是長這樣的:

鼠標(biāo)點(diǎn)擊的位置,可以取值各個圖片的中心點(diǎn):

這個值可以計算:

  • width: 37, 37 * 3, 37 * 5, 37 * 7; 即37, 111, 185, 259
  • height(0): 70
  • height(1): 70 + (190-30)/2, 即150

當(dāng)驗(yàn)證碼圖片的坐標(biāo)為x,y時;鼠標(biāo)點(diǎn)擊第2,7張圖片的位置可以表達(dá)為(x+111, y+70),(x+185, y+150)

示例:

import asyncio import random from pyppeteer import launchasync def main():browser = await launch({'headless': False,'args': [f'--window-size=1366,768', '--no-sandbox']})page = await browser.newPage()await page.goto('https://kyfw.12306.cn/otn/login/init',{'waitUntil': 'networkidle0'})await page.setViewport({'width': 1366, 'height': 768})# 等待驗(yàn)證碼加載code = await page.waitForFunction('''() => document.querySelector("img.touclick-image")''')# 驗(yàn)證碼截圖await code.screenshot({'path': 'code.png'})# 獲取驗(yàn)證碼坐標(biāo)box = await code.boundingBox()await page.waitFor(2 * 1000)# 點(diǎn)擊第2張圖片await page.mouse.click(box['x']+111, box['y']+70)await page.waitFor(random.randint(567, 3456))# 點(diǎn)擊第7張圖片await page.mouse.click(box['x']+185, box['y'] + 150)await page.waitFor(3 * 1000)await browser.close()asyncio.get_event_loop().run_until_complete(main())

(2) 打碼平臺:12306的

驗(yàn)證碼識別有點(diǎn)反人類;對接打碼平臺是比較不錯的選擇;原理就是把驗(yàn)證碼圖片以字節(jié)的方式發(fā)給他們,返回一個字符串,例如:183,68|193,161;

超級鷹打碼平臺API:

chaojiying.py

#!/usr/bin/env python # coding:utf-8import requests from hashlib import md5class CodeInfo(object):def __init__(self):self.username = '用戶名'self.password = md5('密碼'.encode('utf8')).hexdigest()self.soft_id = '96001' # 用戶中心 >> 軟件ID,生成一個替換96001self.base_params = {'user': self.username,'pass2': self.password,'softid': self.soft_id,}self.headers = {'Connection': 'Keep-Alive','User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',}def process(self, im, codetype):url = 'http://upload.chaojiying.net/Upload/Processing.php'params = {'codetype': codetype}params.update(self.base_params)files = {'userfile': ('ccc.jpg', im)}r = requests.post(url, data=params, files=files, headers=self.headers)return r.json()def report(self, im_id):"""im_id:報錯題目的圖片ID"""url = 'http://upload.chaojiying.net/Upload/ReportError.php'params = {'id': im_id}params.update(self.base_params)r = requests.post(url, data=params, headers=self.headers)return r.json()if __name__ == '__main__':im = open('code.png', 'rb').read()"""9004 驗(yàn)證碼類型參考 http://www.chaojiying.com/price.html"""answer = CodeInfo().process(im, 9004)print(answer)

登錄12306的例子

import asyncio import random from pyppeteer import launch from chaojiying import CodeInfodef pic_info():im = open('code.png', 'rb').read()answer = CodeInfo().process(im, 9004)print(answer)return answer['pic_str']async def main():browser = await launch({'headless': False,'args': ['--window-size=1366,768', '--no-sandbox']})page = await browser.newPage()await page.goto('https://kyfw.12306.cn/otn/login/init',{'waitUntil': 'networkidle0'})await page.setViewport({'width': 1366, 'height': 768})code =await page.waitForFunction('''() => document.querySelector("img.touclick-image")''')await code.screenshot({'path': 'code.png'})await page.waitFor(2 * 1000)await page.type('#username', '123456789@qq.com',{'delay': random.randint(60, 121)})await page.waitFor(random.randint(345, 1234))await page.type('#password', '1234567890',{'delay': random.randint(100, 151)})pic_str = pic_info()points = list(set(pic_str.split('|')))box = await code.boundingBox()for point in points:p = point.split(',')await page.mouse.click(box['x']+int(p[0]), box['y']+int(p[1]))await page.waitFor(random.randint(567, 3456))await page.click('#loginSub')await page.waitFor(5 * 1000)await browser.close()asyncio.get_event_loop().run_until_complete(main())

鍵盤事件

Keyboard 提供一個接口來管理虛擬鍵盤. 高級接口為keyboard.type,其接收原始字符,然后在你的頁面上生成對應(yīng)的keydown,keypress/input,和keyup事件。

為了更精細(xì)的控制(虛擬鍵盤),你可以使用keyboard.down, keyboard.up和keyboard.sendCharacter來手動觸發(fā)事件,就好像這些事件是由真實(shí)的鍵盤生成的。

鍵盤的幾個API如下:

  • keyboard.down(key[, options])觸發(fā)keydown事件
  • keyboard.press(key[, options])按下某個鍵,key表示鍵的名稱,比如'ArrowLeft'向左鍵;
  • keyboard.sendCharacter(char)輸入一個字符
  • keyboard.type(text, options)輸入一個字符串
  • keyboard.up(key)觸發(fā)keyup事件

?

持續(xù)按下shift來選擇一些字符串并且刪除的例子:

import asyncio from pyppeteer import launchasync def main():browser = await launch({'headless': False})page = await browser.newPage()await page.goto('https://www.baidu.com', {'waitUntil': 'networkidle0'})el = await page.J('#kw')await el.focus()await page.keyboard.type('Hello, World!')await page.keyboard.press('ArrowLeft')await page.keyboard.down('Shift')for _ in ' World':await page.keyboard.press('ArrowLeft')await page.keyboard.press('ArrowLeft')await page.keyboard.up('Shift')await page.keyboard.press('Backspcae')# 結(jié)果字符串最終為'Hello!'await asyncio.sleep(5)await browser.close()asyncio.get_event_loop().run_until_complete(main())

按下?A的例子:

await page.keyboard.down('Shift') await page.keyboard.press('KeyA') await page.keyboard.up('Shift')

詳細(xì)的健名映射可以看源碼:

Lib\site-packages\pyppeteer\us_keyboard_layout.py

內(nèi)嵌框架

可以通過 Page.frames、ElementHandle.contentFrame方法獲取,同時具有和page多個方法;

**其它:

  • childFrames 獲取子框架,返回列表
  • parentFrame 返回父框架
  • content() 返回框架的 html 內(nèi)容
  • url 獲取 url
  • name 獲取 name
  • title() 獲取 title


?

例子:

import asyncio from pyppeteer import launchasync def main():browser = await launch({'headless': False})page = await browser.newPage()await page.goto('http://www.4399.com', {'waitUntil': 'networkidle0'})await page.click('#login_tologin')await asyncio.sleep(1)frame = page.frames[1]await frame.type('#username', '123456789')await frame.type('#j-password', '998765433')await asyncio.sleep(5)await browser.close()asyncio.get_event_loop().run_until_complete(main())

或者:

await page.click('#login_tologin') await asyncio.sleep(1) element = await page.J('iframe') frame = await element.contentFrame()

?

總結(jié)

以上是生活随笔為你收集整理的Pyppeteer库之四:Pyppeteer的页面操作(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。