来点接地气的,继续部门的老 web 自动化框架解读,这次里面一些偏方
windows 环境在启动自动化前的清理工作
因为自动化是根据不同的 hosts 来确定对应版本环境,所以要进行清理上次运行的代理、dns 缓存,于是有以下代码片段(修改注册表)文章源自玩技e族-https://www.playezu.com/180065.html
import os
cmd_switchProxy="chcp 65001 & reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f & "+
"reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "" /f & "+
"ipconfig /flushdns"
with os.popen(cmd_switchProxy,"r") as f: print('清理系统代理及dns缓存:',f.read())
windows 环境关闭掉 chrome 的 trigger 页面
chromedriver 打开 chrome 默认会打开一个 trigger 页面,让人心烦,同样也是修改注册表来关闭它文章源自玩技e族-https://www.playezu.com/180065.html
import os
cmd_closeTrigger="chcp 65001 & reg delete HKEY_CURRENT_USERSoftwareGoogleChromeTriggeredReset /f"
with os.popen(cmd_closeTrigger,"r") as f:print('关闭chrome的Trigger页面:',f.read())
模拟 ajax
webdriver 可以执行 js 和异步 js,但貌似无法执行 ajax,于是有如下模拟 ajax 的方法。
方法比较简单:利用 requests 库 +webdriver 获取 cookie 字符串 + 特殊请求头而已,这样可以模拟 ajax 执行一些请求了文章源自玩技e族-https://www.playezu.com/180065.html
import requests
def getAjaxedRequsetSession(driver:webdriver,proxy_ip:str,proxy_port:int) -> requests.Session:
cookies=driver.get_cookies()
cookieString="; ".join([c["name"]+"="+c["value"] for c in Cookie])
requestSession=requests.Session()
requestSession.trust_env=False
requestSession.headers.update(
{
'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4478.0 Safari/537.36",
'Cookie': cookieString,
'x-requested-with':'XMLHttpRequest',
'Sec-Fetch-Site': 'same-origin'
}
)
if proxy_ip and proxy_port:
requestSession.proxies={
'http':'http://%s:%d'%(proxy_ip,proxy_port),
'https':'https://%s:%d'%(proxy_ip,proxy_port)
}
return requestSession
精确的转到新打开的窗口
一些人转到新打开的窗口都是通过 title 来定位,但如果 title 重复、没有 title 咋办?
方法也比较简单:先获取当前窗口的句柄列表,执行某个操作后,再获取之后的的窗口句柄列表,找到多出来的那个就好了。
打开新窗口一般都是点击操作,而且一般是打开一个窗口(其他情况是反人类的)
以下方法 通过点击元素跳转到新的窗口,并返回原窗口的句柄,便于操作完成返回原先窗口文章源自玩技e族-https://www.playezu.com/180065.html
def switchToNewWindowByClick(driver:webdriver,element:WebElement):
"""
通过点击元素跳转到新的窗口
:param element:
:return:
"""
currentHandle = driver.current_window_handle
preAllHandles = set(driver.window_handles)
element.click()
time.sleep(5)
nxtAllHandles = set(driver.window_handles)
newHandles=nxtAllHandles.difference(preAllHandles)
if len(newHandles)<1:
return False,currentHandle
newWindow=newHandles.pop()
try:
driver.switch_to.window(newWindow)
return True,currentHandle
except NoSuchWindowException as nswe:
print(nswe.msg)
traceback.print_exc()
return False,currentHandle
chrome 和 firefox 的忽略证书错误
测试环境的 ssl 证书错误比较烦人,一般要忽略证书错误来做,方法也能百度到,如下:
firefox 的文章源自玩技e族-https://www.playezu.com/180065.html
GeckodriverDriverPath="Geckodriver的路径"
firefoxProfiles=[
("network.http.phishy-userpass-length", 255),
("webdriver_assume_untrusted_issuer",False),
]
firefox_profile = webdriver.FirefoxProfile()
for profile in firefoxProfiles:
firefox_profile.set_preference(profile[0],profile[1])
driver = webdriver.Firefox(executable_path=GeckodriverDriverPath,firefox_profile=firefox_profile)
chrome 的文章源自玩技e族-https://www.playezu.com/180065.html
ChromeDriverPath="chromedriver的路径"
chromeOptions=['--demo-type','--ignore-certificate-errors']
for option in chromeOptions:
chrome_options.add_argument(option)
driver = webdriver.Chrome(executable_path=ChromeDriverPath,options=chrome_options)
xpath 的文本中包含单引号 (') 和双引号 (") 问题
假如有这样一个元素:<div> "双",'单' </div>
。那 xpath 应该怎样写?
【1】是//div[contains(text(),"A")]
或者//div[contains(text(),'B')]
格式吗
A、B 中内容有单双引号,与包裹他们的双、单引号是冲突的,xpath 中可不认转义符"或',所以不可行
【2】投机取巧//div[contains(text(),'"双",') and contains(text(),"'单'") ]
这种方法只能特殊情况特殊处理,不具备普遍性,不适合用于自动化框架中
【3】利用 concat 函数是正确方法,如://div[contains(text(),concat('"双"',",'单'")) ]
生成的字符串方式会很多,通用方法是将单/双引号做分割符,然后再拼接。于是有了如下方法:文章源自玩技e族-https://www.playezu.com/180065.html
def fixXpathText(text:str):
"""
处理用xpath文本使用text()定位时,里面包含单引号、双引号情况
生成xpath中的字符串
:param text:
:return:
"""
x=text.split('"')
if len(x)==1:
return """+text+"""
y=[]
for s in x[:-1]:
y.append(s)
y.append('"')
y.append(x[-1])
ts="concat("
te=")"
for t in y[:-1]:
if """==t:
ts+="'"',"
continue
ts+="""+t+"","
if """==y[-1]:
ts+="'"',"
else:
ts+="""+y[-1]+"""
return ts+te
效果如下(虽不精炼,但够用)
评论