借用朋友的资源(感恩~),搭建了一个简单的电商商城,来实操一下相关元素定位方法,具体业务为:登录商城-->搜索所需商品-->加入购物车-->结算-->添加新的收货地址,记录总结相关元素定位方法,以及遇到的一些问题和解决问题的方法。
可以查看到用户名、密码输入框均有id属性,可以直接使用id来定位,写法如下:
chromedriver.find_element_by_id("username").send_keys("xiao")
chromedriver.find_element_by_id("password").send_keys("123456")
可以查看到登录按钮对应有class属性, 如果直接copy后,按照如下写法,运行后发现,代码会报错(问题1)。
chromedriver.find_element_by_class_name("login_btn fl").click()
报错内容部分如下:
这里需要说明一下,原因是不允许使用复合类名,这里很容易分辨“login_btn”这个为唯一的,则仍可以使用class_name来定位,如若发现不知道如何区分的,则可以则可以使用css_selector来定位,后面再举例说明,此处登录按钮的点击事件写法修改后如下:
chromedriver.find_element_by_class_name("login_btn").click()
# 进入商城
chromedriver.find_element_by_link_text("进入商城购物").click()
然而此处代码运行后,会发现商城网页没有执行“进入商城购物”的点击事件(问题2),再次运行代码,观察网页变化发现,点击登录后网页会先显示一个“登录成功”的界面,随后才变化为上图3的界面。
图4 登录成功
遇到此种情况,可以加一个等待时间,代码修改如下:
# 进入商城
time.sleep(3)
chromedriver.find_element_by_link_text("进入商城购物").click()
此处补充说明一下时间等待的相关问题,上述时间等待的方式,并不一定每次均有效,可能因为网速等原因,等待了3秒仍没有跳转到想要的页面,这里推荐另一种方式,隐式等待。在打开浏览器后,即可加入隐式等待,写法如下:
chromedriver.implicitly_wait(10)
隐式等待优点:
1、括号中的数值只是最大等待时间,会智能的判断,下一行代码应该等待多久再执行;
2、只需要写一次,后面所有代码都生效;
# 搜索商品
chromedriver.find_element_by_name("keyword").send_keys("iphone")
chromedriver.find_element_by_class_name("btn1").click()
右键copy-->copy xpath ,可以直接copy出所需内容,写法如下:
# 点击商品图片,进入商品详情页
chromedriver.find_element_by_xpath("/html/body/div[3]/div[2]/div[3]/div/div[1]/a/img").click()
进入商品详情页后,接下来需要点击“加入购物车”,此时发现了新的问题(问题3),商品详情页打开了新的窗口,这就需要在代码中也先切换到新窗口中,才能继续定位到相关元素,执行后续操作,代码如下:
# 找到新窗口
new_window = chromedriver.window_handles[-1]
# 切换到新窗口
chromedriver.switch_to.window(new_window)
# 点击加入购物车
chromedriver.find_element_by_id("joinCarButton").click()
前面讲用class定位时,也提到了这里的情况,如果无法去拆解这个class,那也可以用css的方式来定位,代码如下:
# 去购物车结算
chromedriver.find_element_by_css_selector(".shopCar_btn_03.fl").click()
在点击结算后,可以去添加新的收货地址,而其中地区的选择市下拉框的方式,接下来来分析每一个下拉框的情况。
可以用id定位到第一个下拉框,再调用Select
# 选择收货地区-省
xiao_province = chromedriver.find_element_by_id("add-new-area-select")
Select(xiao_province).select_by_visible_text("山西省")
会发现id是动态变化的,而xpath实际也是用id来定位(//*[@id="linkagesel_373665"]),同理查看css也是用id来定位(#linkagesel_373665)观察发现第二个下拉框的class与第一个相同,这样我们可以用class标签来定位,找到所有相同的class,用数组下标来确定是哪个。
# 选择收货地区-市
xiao_city = chromedriver.find_elements_by_class_name("add-new-area-select")[1]
Select(xiao_city).select_by_visible_text("大同市")
除了上述方式,还可以采用tag标签来定位,可以看出这三个下拉框均使用了select,同样先找到所有相同的select,再用数组下标来确定是哪个。
# 选择收货地区-县
xiao_country = chromedriver.find_elements_by_tag_name("select")[2]
Select(xiao_country).select_by_visible_text("南郊区")
下拉框的定位
(1)定位下拉框: element = driver.find_element...
(2)把找到的页面元素,转换成下拉框的类型Select
(3)调用Select类中的方法:
.select_by_value(选项的value属性的值)
.select_by_index(第几个选项)
.select_by_visible_text(选项的文本值)
本次提到了约8种定位元素的方式,推荐一个使用优先级(id>name>class name>link),除了这4种,还有xpath、css、find_elements...、tag方式,同时在本次业务的自动化实现过程中,也遇到了3个问题,分别是class_name不能使用复合类名、网页需要等待时间、窗口切换(从窗口1切换到窗口2),并给出了相应的解决方案。
成长之路,道阻且长,后续会继续总结自己平时遇到的一些问题,加油!