提醒:pyppeteer 是 puppeteer 的 python 翻版,目前已好久未更新!
网站的前端使用了 Next.js 框架,并在生产上直接使用 NODE 服务。虽然前期开发使用了 K6 做了简单的压力测试报告,但领导还是有些质疑稳定性,要求做好监测:因为时间问题,这个应用还未接入日常监控,只能采用临时方法:web 自动化巡检 PV 高的页面,做一些简单交互,如果有异常,通过公司内部的聊天工具发送异常信息。
因为针对的是前端应用稳定性上,关注点不是具体功能实现上,而是【页面加载后】或【一些交互后】的的表现:
能方便检查浏览器控制台自动化工具目前也不少,选用 pyppeteer 也是因为以前就安装过:pip install pyppeteer。
这个需要配合 chromium,需要单独下载(最好将将其下 chrome.exe 重命名为 chromium.exe,目的是为了其他 chrome 的进程实例区分)
pyppeteer 操作 chromium 比较推荐 connect 方式:
async def connectChromium(debugPort=9222)->typing.Union[None,browser.Browser]:
try:
loop=asyncio.get_event_loop()
resp=await loop.run_in_executor(None,functools.partial(requests.get,url='http://localhost:%d/json/version'%debugPort))
if resp.status_code==200 and resp.json():
debugUrl=resp.json().get("webSocketDebuggerUrl","")
browser = await pyppeteer.connect(
browserWSEndpoint=debugUrl,
defaultViewport=None,
ignoreHTTPSErrors=True,
ignoreDefaultArgs=['--enable-automation']
)
return browser
except Exception as e:
print("连接 chromium 出现异常:%s"%str(e))
return None
监听浏览器控制台,使用对应的监听回调方法即可:
async def gatherError(msg,checkRstList:list,url:str):
"""
获取控制台中的异常信息
:param msg:
:checkRstList:全局变量,存储异常信息
:url:当前页面的url
:return:
"""
if msg._type=="error":
# 一些埋点类请求无法连接,忽略掉;真的网站的网络异常会有页面异常来判断(看具体情况过滤)
if msg._text.find("ERR_CONNECTION_")>=0 :
return
logging.error("PAGE [%s] has js error: %s"%(url,msg._text))
if msg._text.find("responded with a status of 500") >= 0 or \
len(re.findall("Uncaught .+Error", msg._text, re.I | re.M)) > 0:
checkRstList.append({
"time":datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
"type":ErrorType.ConsoleError,
"msg":"页面[%s]有js错误:%s"%(url,msg._text)
})
async def gatherPageError(err:PageError,checkRstList:list,url:str):
"""
获取页面异常信息
:param msg:
:return:
"""
checkRstList.append({
"time": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
"type": ErrorType.PageError,
"msg": "页面[%s]有页面错误:%s" % (url, str(err))
})
pages = await browser.pages()
if not pages: # 只使用第1个标签页
page = await browser.newPage()
else:
page =pages[0]
# 消除webdriver标记
await page.evaluateOnNewDocument(r'''()=>{
const newProto = navigator.__proto__;
delete newProto.webdriver;
navigator.__proto__ = newProto;
}''')
# 注册page的控制台消息事件,设置回调方法,非异步方法
page.on('console',lambda msg: asyncio.ensure_future(common.gatherError(msg,checkRstList,current_url)))
page.on('pageerror',lambda error: asyncio.ensure_future(common.gatherPageError(error,checkRstList,current_url)))
其他的页面检查都是正常的自动化,就不赘述了
后续:
上周末,收到大量 “搜索交互出现异常” 的消息。告知前端负责人,重新服务后正常,说明该应用还是有不稳定的地方,已通知他们排查原因