iOS 13 适配TextField 崩溃问题

iOS 13 之后直接通过以下方式修改Textfield的时候会出现报错信息

[_accountText setValue:Color_666666 forKeyPath:@”_placeholderLabel.textColor”];

报错信息

Access to UITextField’s _placeholderLabel ivar is prohibited. This is an application bug

解决方式

NSMutableAttributedString *passwordPlaceholderString = [[NSMutableAttributedString alloc] initWithString:@”账号密码” attributes:@{NSForegroundColorAttributeName : Color_666666}];
_passwordText.attributedPlaceholder = passwordPlaceholderString;

iphonex适配 Home Indicator隐藏

全屏游戏Home Indicator太碍眼,想把它隐藏掉。

找到这个方法:

– (BOOL)prefersHomeIndicatorAutoHidden {
return YES;
}
但是有个问题,每次触摸屏幕,Home Indicator又会出现, 停止触摸后大概 两三秒又会消失。但是对于需要不断操作的 游戏来说,这行代码没啥用。

我比较喜欢大话西游、剑与家园那样的效果,Home Indicator是半透明的,上划一次被激活,再划一次就回回到主界面。

找到以下代码可以实现:

-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}
ps:主要是自己记录一下,老鸟请无视。

iOS13踩坑记录

1、UIViewController切换方式modalPresentationStyle

iOS13默认UIModalPresentationAutomatic模式,不符合我们的需求。改回之前的模式要用UIModalPresentationFullScreen。

vc.modalPresentationStyle = UIModalPresentationFullScreen;

但是,问题来了,项目里vc太多,而且因为接入了多家SDK,viewController并没有一个相同父VC,全局改太费劲了。

解决方案:

在appDelegate中实现了ViewController的分类,改变了modalPresentationStyle的值完美解决。

@implementation UIViewController(modalPresentationStyle)

– (UIModalPresentationStyle)modalPresentationStyle{

return UIModalPresentationFullScreen;

}

@end
2、”NSGenericException” – reason: “Access to UITextField’s _placeholderLabel ivar is prohibited. This is an application bug”

设置TextFiled的默认文字颜色在iOS13 Crash。

[textfield setValue:[UIColor whiteColor] forKeyPath:@”_placeholderLabel.textColor”];
查了一下,帖子挺多的,解决方案:

Ivar ivar = class_getInstanceVariable([UITextField class], “_placeholderLabel”);
UILabel *placeholderLabel = object_getIvar(textField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];
记得加头文件

#import <objc/runtime.h>
未完待续。。

iOS13 新特性简介

目录

  • 一、Dark Mode 暗黑模式
  • 二、Status Bar更新
  • 三、UIActivityIndicatorView加载视图
  • 四、总结

一、Dark Mode 暗黑模式

1.1 iOS13推出了Dark Mode

%title插图%num
Dark Mode

1.2 UIColor拥有了动态属性

%title插图%num
iOS13之前只能表示一种颜色
%title插图%num
iOS13以后能够表示两种模式下的不同颜色

1.3 图片也能在两种模式下自由切换

%title插图%num
iOS13 两种模式下的图片资源

1.4 Dark Mode 模式适配

 


二、Status Bar更新

  • iOS13对Status BarAPI做了修改
  • 之前Status Bar有两种状态
    • UIStatusBarStyleDefault 文字黑色
    • UIStatusBarStyleLightContent 文字白色
%title插图%num
iOS13以前Status Bar样式
  • iOS13以后有三种状态
    • UIStatusBarStyleDefault自动选择黑色或白色
    • UIStatusBarStyleDarkContent文字黑色
    • UIStatusBarStyleLightContent文字白色
    %title插图%num
    iOS13以后Status Bar有三种状态

三、UIActivityIndicatorView加载视图

  • iOS13对UIActivityIndicatorView的样式也做了修改
  • 之前有三种样式:
    • UIActivityIndicatorViewStyleGray 灰色
    • UIActivityIndicatorViewStyleWhite 白色
    • UIActivityIndicatorViewStyleWhiteLarge 白色(大型)
  • iOS13废弃了以上三种样式,而用以下两种样式代替:
    • UIActivityIndicatorViewStyleLarge (大型)
    • UIActivityIndicatorViewStyleMedium (中型)
  • iOS13通过color属性设置其颜色

3.1 示例

- (UIActivityIndicatorView *)loadingView { if (_loadingView == nil) { _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge]; [_loadingView setColor:[UIColor systemBackgroundColor]]; [_loadingView setFrame:CGRectMake(0, 0, 200, 200)]; [_loadingView setCenter:self.view.center]; } return _loadingView; } 

3.2 效果

%title插图%num
iOS13之前的三种样式
%title插图%num
iOS13以后的两种样式

四、总结

 

iOS13*主要的是推出了暗黑模式Dark Mode,目前App Store榜单上的App已经开始积*适配了
9月份会发布iOS13正式版本,2020年苹果可能要求开发者必须适配Dark Mode,否则不予上架
Status Bar 样式被修改
UIActivityIndicatorView 原有的三种样式全部被废弃,推出两种新的样式

web自动化-元素模糊定位方法

web自动化-元素模糊定位方法

 

常见元素定位方法,主要是通过id,class,xpath等,这些元素有时它的属性值是随机的,但同时又有一定的规律,为了提高代码定位元素的准确性,我们寻找其规律,然后集成到元素中进行重构。

元素模糊定位,即对页面元素属性值进行部分匹配。元素属性值的匹配方式主要有三种,分别是”starts-with”,“ends-with”和”contains”,text()

 

starts-with 匹配一个属性开始位置的关键字

 

ends-with 匹配一个属性结束位置的关键字

 

contains 匹配一个属性值中包含的字符串

 

text() 匹配的是显示文本信息,此处也可以用来做定位用

 

如下html页面代码:

 

<!DOCTYPE html>

<html lang=”en”>

<head>

   <meta charset=’UTF-8′>

   <title> 陕西区域划分(只包括部分)</title>

</head>

<body>

<div name=”区域划分”>

<a id = “gaoxin_123_gao”>高新区</a>

<a id = “beilin_234_bei”>碑林区</a>

<a id = “weiyang_456_wei”>未央区</a>

<a id = “changan_567_chang”>长安区</a>

</div>

</body>

</html>

 

以上html代码可以看出,区县信息的id前后部分是固定的,但中间部分数字是随机的,这个时候可以通过xpath模糊定位方法进行元素定位。

 

1、通过starts-with定位

 

//*[starts-with(@id,‘gaoxin’)]

 

2、通过ends-with定位

 

//*[ends-with(@id,‘gao’)]

 

3、通过contains定位

 

//*[contains(@id,‘gao’)]

 

4、通过显示的文本进行定位

 

//a[text()=‘高新区’]

 

//a[contains(text(),‘高新区’)]

 

pip install安装报错

pip install安装报错

pip install PrettyTable报错
1. 安装升级pip

wget https://bootstrap.pypa.io/pip/2.7/get-pip.py

python get-pip.py -i http://pypi.douban.com/simple –trusted-host pypi.douban.com

2. 安装PrettyTable

$ pip install PrettyTable
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)’: /simple/prettytable/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)’: /simple/prettytable/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)’: /simple/prettytable/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)’: /simple/prettytable/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)’: /simple/prettytable/
Could not fetch URL https://pypi.tuna.tsinghua.edu.cn/simple/prettytable/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host=’pypi.tuna.tsinghua.edu.cn’, port=443): Max retries exceeded with url: /simple/prettytable/ (Caused by SSLError(SSLError(1, u'[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)’),)) – skipping
ERROR: Could not find a version that satisfies the requirement PrettyTable (from versions: none)
ERROR: No matching distribution found for PrettyTable

如果遇到上述错误提示,记得使用如下命令更换源进行安装

pip install PrettyTable -i http://pypi.douban.com/simple –trusted-host pypi.douban.com

leetcode—11.队列题型python解答

leetcode—11.队列题型python解答

文章目录
125. 验证回文串
232. 用栈实现队列
239. 滑动窗口*大值
125. 验证回文串
这里使用双端队列来解决回文串问题

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。

class Solution:
def isPalindrome(self, s: str) -> bool:
s = s.lower()
# 检测字母与数字字符
s = [i for i in s if i.isalpha() or i.isnumeric()]
# 构造双端队列
deque = collections.deque()
# 回文词入对
for i in s:
deque.appendleft(i)
state = True
while len(deque) > 1 and state:
left = deque.popleft()
right = deque.pop()
if left != right:
state = False
return state

232. 用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

解法一:在一个栈中维持所有元素的出队顺序思路

*种方式是在一个栈中维持所有元素的出队顺序,即所有的元素在入队操作完成后只会保存在一个栈中,且其出栈的顺序和出队的顺序是一致的。通俗理解来说,相当于一个栈是中间容器

class MyQueue:

def __init__(self):
“””
Initialize your data structure here.
“””
self._s1,self._s2 = [],[]

def push(self, x: int) -> None:
“””
Push element x to the back of queue.
“””
# 为了维持栈1的出队顺序,当栈1中有元素,后续还要添加元素,需要先将栈1中的元素移到栈2,等栈1添加完之后,再将栈1的元素添加到栈1
while self._s1:
self._s2.append(self._s1.pop())
self._s1.append(x)
while self._s2:
self._s1.append(self._s2.pop())

def pop(self) -> int:
“””
Removes the element from in front of queue and returns that element.
“””
return self._s1.pop()

def peek(self) -> int:
“””
Get the front element.
“””
return self._s1[-1]

def empty(self) -> bool:
“””
Returns whether the queue is empty.
“””
return self._s1 == []

解法二:一个栈入,一个栈出
思路:

解法二的实现方式与解法一有点不同,按照功能的不同,解法二将两个栈一个用于入队,—个用于出队。假设栈inStack 用于实现入队操作,栈outStack 用于实现出队操作。

class MyQueue:

def __init__(self):
“””
Initialize your data structure here.
“””
# self,_front用于存储入栈的栈首元素
self._in_stack,self._out_stack,self._front = [],[],None

def push(self, x: int) -> None:
“””
Push element x to the back of queue.
“””
# 保存入栈的栈首元素
if not self._in_stack:
self._front = x
self._in_stack.append(x)

def pop(self) -> int:
“””
Removes the element from in front of queue and returns that element.
“””
if self.empty():
raise Exception(‘The queue is empty!’)
# 将输入栈元素全部添加到输出栈
if not self._out_stack:
while self._in_stack:
self._out_stack.append(self._in_stack.pop())
return self._out_stack.pop()

def peek(self) -> int:
“””
Get the front element.
“””
if self.empty():
raise Exception(‘The queue is empty!’)

if not self._out_stack:
return self._front
else:
return self._out_stack[-1]

def empty(self) -> bool:
“””
Returns whether the queue is empty.
“””
return self._in_stack == [] and self._out_stack == []

239. 滑动窗口*大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的*大值

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:
滑动窗口的位置 *大值

[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
res = [] # 存储结果
# 双端队列,两端快速添加(append)和弹出(pop),维护的是窗口内*大值的索引
queue = collections.deque()
for i, num in enumerate(nums):
# 将不在窗口内的*大值的索引弹出
if queue and queue[0] == i – k:
queue.popleft()
# 如果队尾的值比num小,则直接弹出
while queue and nums[queue[-1]] < num:
queue.pop()
# 队尾添加元素
queue.append(i)
# 每个窗口保存一个*大值
if i >= k – 1:
res.append(nums[queue[0]])
return res

python笔记:异常及异常处理

python笔记:异常及异常处理

1. 异常的概念:
• 程序在运行时,如果 Python 解释器遇到到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常
• 程序停止执行并且提示错误信息这个动作,我们通常称之为:抛出(raise)异常

程序开发时,很难将 所有的特殊情况 都处理的面面俱到,通过 异常捕获 可以针对突发事件做集中的处理,从而保证程序的 稳定性和健壮性

2. 捕获异常
2.1 简单的捕获异常语法
• 在程序开发中,如果对某些代码的执行不能确定是否正确,可以增加 try(尝试) 来捕获异常
•捕获异常*简单的语法格式:

try:
尝试执行的代码《不确定是否能正常执行》
except:
编写尝试失败的代码《即以上代码不能正常执行》

无论是否有异常,代码都会往后执行

简单异常捕获演练 —— 要求用户输入整数

try:
num = int(input(“请输入数字:”)) # 提示用户输入一个数字
except:
print(“请输入正确的数字”)

2.2 错误类型捕获

• 在程序执行时,可能会遇到不同类型的异常,并且需要针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
•语法如下:

try:
# 尝试执行的代码 pass
except 错误类型1:
# 针对错误类型1,对应的代码处理
except (错误类型2, 错误类型3):
# 针对错误类型2和3,对应的代码处理
except Exception as result:
print(“未知错误 %s” % result)

当 Python 解释器 抛出异常 时,*后一行错误信息的*个单词,就是错误类型

异常类型捕获演练 —— 要求用户输入整数

需求:
1.提示用户输入一个整数
2.使用 8 除以用户输入的整数并且输出

try:
num = int(input(“请输入整数:”))
result = 8 / num
print(result)
except ValueError: #错误类型1
print(“请输入正确的整数”)
except ZeroDivisionError: #错误类型2
print(“除 0 错误”)

2.3 捕获未知错误
• 在开发时,要预判到所有可能出现的错误,还是有一定难度的
• 如果希望程序无论出现任何错误,都不会因为 Python 解释器抛出异常而被终止,可以再增加一个 except

语法如下:

except Exception as result:
print(“未知错误 %s” % result)
1
2
2.4 异常捕获完整语法
• 在实际开发中,为了能够处理复杂的异常情况,完整的异常语法如下:

try:
# 尝试执行的代码
except 错误类型1:
# 针对错误类型1,对应的代码处理
except 错误类型2:
# 针对错误类型2,对应的代码处理
except (错误类型3, 错误类型4):
# 针对错误类型3和4,对应的代码处理
except Exception as result:
# 打印错误信息 print(result)
else:
# 没有异常才会执行的代码 pass
finally:
# 无论是否有异常,都会执行的代码
print(“无论是否有异常,都会执行的代码”)

之前一个演练的 完整捕获异常 的代码如下:

try:
num = int(input(“请输入整数:”))
result = 8 / num
print(result)
except ValueError:
print(“请输入正确的整数”)
except ZeroDivisionError:
print(“除 0 错误”)
except Exception as result:
print(“未知错误 %s” % result)
else:
print(“正常执行”)
finally:
print(“执行完成,但是不保证正确”)

case1:
请输入整数:8
1.0
正常执行
执行完成,但是不保证正确
case2:
请输入整数:0.2
请输入正确的整数
执行完成,但是不保证正确

3. 异常的传递
• 异常的传递 —— 当函数/方法执行出现异常,会将异常传递给函数/方法的调用一方
• 如果传递到主程序,仍然没有异常处理,程序才会被终止

提示:
• 在开发中,可以在主函数中增加异常捕获
• 而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获 中
• 这样就不需要在代码中,增加大量的异常捕获,能够保证代码的整洁

需求
1.定义函数 demo1() 提示用户输入一个整数并且返回
2.定义函数 demo2() 调用 demo1()
3.在主程序中调用 demo2()

def demo1():
return int(input(“请输入一个整数:”))

def demo2():
return demo1()

try:
print(demo2())
except ValueError:
print(“请输入正确的整数”)
except Exception as result:
print(“未知错误 %s” % result)

4. 抛出 raise 异常
• 在开发中,除了代码执行出错 Python 解释器会抛出异常之外,还可以根据应用程序特有的业务需求主动抛出异常
• Python 中提供了一个 Exception 异常类【也可以自己定义异常类】
• 在开发时,如果满足特定业务需求时,希望抛出异常,可以:
1.创建 一个 Exception 的对象
2.使用 raise 关键字抛出异常对象

try:
print(“请输入登录账号: “)
username = input(“>> “)
if username != “zhangsan”:
raise Exception(“用户名输入错误”)
print(“请输入登录密码: “)
password = input(“>>: “)
if (password != “123456”):
raise Exception(“密码输入错误”)
except Exception as e:
print(e)

使用raise语句主动抛出异常的意思是开发者可以自己制造程序异常,这里的程序异常不是指发生了内存溢出、列表越界访问等系统异常,而是指程序在执行过程中,**发生了用户输入的数据与要求数据不符、用户操作错误等问题,**这些问题都需要程序进行处理并给出相应的提示

assert断言:
assert 语句,又称断言语句,可以看做是功能缩小版的 if 语句,它用于判断某个表达式的值,如果值为真,则程序可以继续往下执行;反之,Python 解释器会报 AssertionError 错误。

assert 语句的语法结构为:

assert 表达式 [, 参数]

当表达式为真时,程序继续往下执行;
当表达式为假时,抛出AssertionError错误,并将 参数 输出

assert 语句的执行流程可以用 if 判断语句表示,如下所示:

if 表达式==True:
程序继续执行
else:
程序报 AssertionError:参数

def foo(s):
n = int(s)
assert n != 0, ‘n is zero!’
return 10 / n

foo(‘0’)

# 代码执行结果
AssertionError: n is zero!

EC2)价格抓取demo

EC2)价格抓取demo

”’
#想使用select方法,但是代码里不是select表单元素,而是awsui-select元素,故放弃

select_2 = Select(dr.find_element_by_xpath(‘//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/div[2]/div/div/div[1]/div[2]/div/div[2]/span[3]/awsui-table/div/div[2]/div/div[2]/span/div/div[2]/div[1]/awsui-select’))
select_2.select_by_value(“2″)
print(‘已经选择了2’)

二:
# action2 = dr.find_element_by_xpath(‘//*[@id=”awsui-select-1″]/div/awsui-icon/span’)
# ActionChains(dr).move_to_element(action2).click(action2).perform() # 鼠标移动到某处单击 ,可用

三:
Advanced_estimate = getElement(dr,’xpath’,’//*[@id=”awsui-radio-button-1”]’)
dr.execute_script(“arguments[0].click();”, Advanced_estimate) #报错,提示按钮被覆盖了,百度搜到了这个方法,可用
”’

from time import sleep
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver import ActionChains #鼠标操作

def getElement(driver,localtorType,localtorExpression):
try:
element = WebDriverWait(driver,60,1).until(lambda x:x.find_element(by = localtorType,value=localtorExpression))
return element
except Exception as e:
driver.quit()
raise e

if __name__ == ‘__main__’:
dr = webdriver.Chrome()
url = ‘https://calculator.aws/#/createCalculator/EC2′ #后期可遍历

dr.maximize_window()
dr.get(url)
sleep(10) # 等loading页面消失

#选择高级模式
Advanced_estimate = getElement(dr,’xpath’,’//*[@id=”awsui-radio-button-1″]’)
Advanced_estimate.click()

# 选择模式 /windows&linux

#选择地域 从0-36个区域
for i in range(37):

region_list = getElement(dr,’xpath’,’//*[@id=”awsui-select-1″]/div/awsui-icon/span’)
region_list.click()

region_xpath = ‘//*[@id=”awsui-select-1-dropdown-option-%d”]/div/div/div/span’%i
region = dr.find_element_by_xpath(region_xpath)
print(‘地区为%s’%region.text)
select_region = getElement(dr,’xpath’,region_xpath)
select_region.click()

#选择change region
change_region = getElement(dr,’xpath’,’//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/awsui-modal/div[2]/div/div/div[3]/span/div/span[2]/awsui-button[2]/button/span/span’)
change_region.click()

sleep(8)

#选择vCPU
vCPU_list = getElement(dr,’xpath’,’//*[@id=”awsui-select-17″]/div/awsui-icon/span’)
vCPU_list.click()

select_2 = getElement(dr,’xpath’,’//*[@title=”4″]’)
select_2.click()
print(‘已经变成4了’)

# 选择memory
memory_list = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-select-18″]/div/awsui-icon/span’)
memory_list.click()

select_4 = getElement(dr, ‘xpath’, ‘//*[@title=”16 GiB”]’)
select_4.click()
print(‘已经变成16了’)

#选择付款模式,先包月后按量
#包月
baoyue = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-radio-button-9″]’)
baoyue.click()
sleep(2)
price = dr.find_element_by_xpath(‘//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/div[2]/div/div/div[2]/div[2]/div[1]/div[6]/div[2]/h4’)
print(‘包月价格为%s’%price.text)

#按量
anliang = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-radio-button-10″]’)
anliang.click()
sleep(2)
price = dr.find_element_by_xpath(‘//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/div[2]/div/div/div[2]/div[2]/div[1]/div[6]/div[2]/h4’)
print(‘按量价格为%s’ % price.text)

#10.89 / 12.06
sleep(15)
dr.close()

window版本:

from time import sleep
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver import ActionChains #鼠标操作

def getElement(driver,localtorType,localtorExpression):
try:
element = WebDriverWait(driver,60,1).until(lambda x:x.find_element(by = localtorType,value=localtorExpression))
return element
except Exception as e:
driver.quit()
raise e

if __name__ == ‘__main__’:
dr = webdriver.Chrome()
url = ‘https://calculator.aws/#/createCalculator/EC2′ #后期可遍历

dr.maximize_window()
dr.get(url)
sleep(15) # 等loading页面消失

#选择高级模式
Advanced_estimate = getElement(dr,’xpath’,’//*[@id=”awsui-radio-button-1″]’)
Advanced_estimate.click()

# 选择模式 /windows&linux
select_mode = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-select-5″]/div/awsui-icon/span’)
select_mode.click()

mode = getElement(dr, ‘xpath’, ‘//*[@title=”Windows Server”]’)
mode.click()
sleep(5)

#选择地域 从0-36个区域
for i in range(37):

region_list = getElement(dr,’xpath’,’//*[@id=”awsui-select-1″]/div/awsui-icon/span’)
region_list.click()

region_xpath = ‘//*[@id=”awsui-select-1-dropdown-option-%d”]/div/div/div/span’%i
region = dr.find_element_by_xpath(region_xpath)
print(‘地区为%s’%region.text)
select_region = getElement(dr,’xpath’,region_xpath)
select_region.click()

#选择change region
change_region = getElement(dr,’xpath’,’//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/awsui-modal/div[2]/div/div/div[3]/span/div/span[2]/awsui-button[2]/button/span/span’)
change_region.click()

sleep(10)

#选择vCPU
# vCPU_list = getElement(dr,’xpath’,’//*[@id=”awsui-select-42″]/div/awsui-icon/span’)
vCPU_list = getElement(dr,’xpath’,’//*[@class=”select-filter vcpu-filter”]’)
vCPU_list.click()

select_2 = getElement(dr,’xpath’,’//*[@title=”4″]’)
select_2.click()
print(‘已经变成4了’)

# 选择memory //*[@class=”select-filter memory-filter”]
# memory_list = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-select-43″]/div/awsui-icon/span’)
memory_list = getElement(dr, ‘xpath’, ‘//*[@class=”select-filter memory-filter”]’)
memory_list.click()

select_4 = getElement(dr, ‘xpath’, ‘//*[@title=”16 GiB”]’)
select_4.click()
print(‘已经变成16了’)

#选择付款模式,先包月后按量
#包月
baoyue = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-radio-button-9″]’)
baoyue.click()
sleep(2)
price = dr.find_element_by_xpath(‘//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/div[2]/div/div/div[2]/div[2]/div[1]/div[6]/div[2]/h4’)
print(‘包月价格为%s’%price.text)

#按量
anliang = getElement(dr, ‘xpath’, ‘//*[@id=”awsui-radio-button-10″]’)
anliang.click()
sleep(2)
price = dr.find_element_by_xpath(‘//*[@id=”e-c2next”]/div/div[2]/awsui-form/div/div[2]/span/span/div[2]/div/div/div[2]/div[2]/div[1]/div[6]/div[2]/h4’)
print(‘按量价格为%s’ % price.text)

#10.89 / 12.06
sleep(15)
dr.close()

Linux:

地区为Africa (Cape Town)
已经变成4了
已经变成16了
包月价格为14.19 USD
按量价格为16.01 USD
地区为Asia Pacific (Hong Kong)
已经变成4了
已经变成16了
包月价格为13.91 USD
按量价格为15.88 USD
地区为Asia Pacific (Tokyo)
已经变成4了
已经变成16了
包月价格为12.73 USD
按量价格为14.55 USD
地区为Asia Pacific (KDDI) – Tokyo
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为58.98 USD
地区为Asia Pacific (Seoul)
已经变成4了
已经变成16了
包月价格为32.33 USD
按量价格为47.37 USD
地区为Asia Pacific (SKT) – Daejeon
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为51.73 USD
地区为Asia Pacific (Osaka)
已经变成4了
已经变成16了
包月价格为34.63 USD
按量价格为49.30 USD
地区为Asia Pacific (Mumbai)
已经变成4了
已经变成16了
包月价格为30.00 USD
按量价格为42.11 USD
地区为Asia Pacific (Singapore)
已经变成4了
已经变成16了
包月价格为33.83 USD
按量价格为48.13 USD
地区为Asia Pacific (Sydney)
已经变成4了
已经变成16了
包月价格为34.50 USD
按量价格为48.73 USD
地区为Canada (Central)
已经变成4了
已经变成16了
包月价格为31.21 USD
按量价格为43.76 USD
地区为EU (Frankfurt)
已经变成4了
已经变成16了
包月价格为32.09 USD
按量价格为45.08 USD
地区为EU (Stockholm)
已经变成4了
已经变成16了
包月价格为28.68 USD
按量价格为40.36 USD
地区为EU (Milan)
已经变成4了
已经变成16了
包月价格为31.80 USD
按量价格为44.72 USD
地区为EU (Ireland)
已经变成4了
已经变成16了
包月价格为30.24 USD
按量价格为42.58 USD
地区为EU (London)
已经变成4了
已经变成16了
包月价格为31.51 USD
按量价格为44.29 USD
地区为EU (Paris)
已经变成4了
已经变成16了
包月价格为31.51 USD
按量价格为44.29 USD
地区为Middle East (Bahrain)
已经变成4了
已经变成16了
包月价格为33.29 USD
按量价格为46.87 USD
地区为South America (Sao Paulo)
已经变成4了
已经变成16了
包月价格为42.02 USD
按量价格为62.90 USD
地区为US East (N. Virginia)
已经变成4了
已经变成16了
包月价格为28.04 USD
按量价格为39.36 USD
地区为US East (Boston)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为156.34 USD
地区为US East (Houston)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为156.34 USD
地区为US East (Miami)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为156.34 USD
地区为US East (Ohio)
已经变成4了
已经变成16了
包月价格为85.13 USD
按量价格为130.46 USD
地区为AWS GovCloud (US-East)
已经变成4了
已经变成16了
包月价格为101.29 USD
按量价格为154.00 USD
地区为AWS GovCloud (US-West)
已经变成4了
已经变成16了
包月价格为101.29 USD
按量价格为154.00 USD
地区为US West (N. California)
已经变成4了
已经变成16了
包月价格为101.44 USD
按量价格为155.02 USD
地区为US West (Oregon)
已经变成4了
已经变成16了
包月价格为85.13 USD
按量价格为130.46 USD
地区为US West (Los Angeles)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为155.37 USD
地区为US West (Verizon) – San Francisco Bay Area
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US West (Verizon) – Las Vegas
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – Atlanta
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – Dallas
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – Miami
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – New York
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – Washington DC
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD
地区为US East (Verizon) – Boston
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为168.02 USD

Windows:
D:\Python3.8.1\Python3.8.1\python.exe C:/Users/frank/PycharmProjects/AWS统计价格/aws_price_windows.py
地区为Africa (Cape Town)
已经变成4了
已经变成16了
包月价格为17.55 USD
按量价格为19.37 USD
地区为Asia Pacific (Hong Kong)
已经变成4了
已经变成16了
包月价格为17.27 USD
按量价格为19.24 USD
地区为Asia Pacific (Tokyo)
已经变成4了
已经变成16了
包月价格为16.09 USD
按量价格为17.91 USD
地区为Asia Pacific (KDDI) – Tokyo
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为72.41 USD
地区为Asia Pacific (Seoul)
已经变成4了
已经变成16了
包月价格为45.76 USD
按量价格为60.80 USD
地区为Asia Pacific (SKT) – Daejeon
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为65.16 USD
地区为Asia Pacific (Osaka)
已经变成4了
已经变成16了
包月价格为48.06 USD
按量价格为62.73 USD
地区为Asia Pacific (Mumbai)
已经变成4了
已经变成16了
包月价格为43.43 USD
按量价格为55.55 USD
地区为Asia Pacific (Singapore)
已经变成4了
已经变成16了
包月价格为47.26 USD
按量价格为61.57 USD
地区为Asia Pacific (Sydney)
已经变成4了
已经变成16了
包月价格为47.93 USD
按量价格为62.17 USD
地区为Canada (Central)
已经变成4了
已经变成16了
包月价格为44.64 USD
按量价格为57.19 USD
地区为EU (Frankfurt)
已经变成4了
已经变成16了
包月价格为45.52 USD
按量价格为58.51 USD
地区为EU (Stockholm)
已经变成4了
已经变成16了
包月价格为42.11 USD
按量价格为53.79 USD
地区为EU (Milan)
已经变成4了
已经变成16了
包月价格为45.23 USD
按量价格为58.15 USD
地区为EU (Ireland)
已经变成4了
已经变成16了
包月价格为43.67 USD
按量价格为56.01 USD
地区为EU (London)
已经变成4了
已经变成16了
包月价格为44.94 USD
按量价格为57.72 USD
地区为EU (Paris)
已经变成4了
已经变成16了
包月价格为44.94 USD
按量价格为57.72 USD
地区为Middle East (Bahrain)
已经变成4了
已经变成16了
包月价格为46.72 USD
按量价格为60.30 USD
地区为South America (Sao Paulo)
已经变成4了
已经变成16了
包月价格为55.45 USD
按量价格为76.33 USD
地区为US East (N. Virginia)
已经变成4了
已经变成16了
包月价格为41.48 USD
按量价格为52.79 USD
地区为US East (Boston)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为210.07 USD
地区为US East (Houston)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为210.07 USD
地区为US East (Miami)
已经变成4了
已经变成16了
包月价格为0.00 USD
按量价格为210.07 USD
地区为US East (Ohio)
已经变成4了
已经变成16了
包月价格为138.86 USD
按量价格为184.19 USD
地区为AWS GovCloud (US-East)
已经变成4了
已经变成16了
包月价格为155.02 USD
按量价格为207.72 USD
地区为AWS GovCloud (US-West)
已经变成4了
已经变成16了
包月价格为155.02 USD
按量价格为207.72 USD
地区为US West (N. California)
已经变成4了
已经变成16了
包月价格为155.17 USD
按量价格为208.75 USD
地区为US West (Oregon)

对百度搜索的一次web自动化测试

对百度搜索的一次web自动化测试

代码:

import unittest
from time import sleep
from selenium import webdriver

class TestBaiDu(unittest.TestCase):
@classmethod
#用setUp,每执行一条测试用例就会启动和关闭一次浏览器,所以此处用setUpClass
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.base_url = “https://www.baidu.com/”

# 模块化,将搜索封装成一个方法
def baidu_search(self,search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id(“kw”).send_keys(search_key)
self.driver.find_element_by_id(“su”).click()
sleep(2)

def test_search_key_selenium(self):
search_key = “selenium”
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+”_百度搜索”)

def test_search_key_unittest(self):
search_key = “unittest”
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+”_百度搜索”)

@classmethod
def tearDownClass(cls):
cls.driver.quit()

if __name__ == ‘__main__’:
unittest.main()
结果:

Ran 2 tests in 17.891s

OK