个人信息修改脚本书写
该脚本以学掌门网站为例,进行登录并进入到个人中心,对个人信息进行修改。主要涉及元素的定位(css_selector、xpath、class_name、tag_name)、对元素的属性值进行修改(删除readonly、修改class值、修改style值)、日历控件的处理、默认值的清除等。
需要提前下载谷歌驱动放置python目录下的Scripts目录下,否则执行脚本会提示找不到driver驱动。下载地址:http://chromedriver.storage.googleapis.com/index.html
1.访问login页面,点击使用【密码登录】:
开发者模式下,查看【密码登录】元素的内容,使用class值来定位:
2.填写账号和密码,点击登录按钮:
可以看到密码框和账号输入框的class都是el-input__inner值,如果想要通过class来定位,如何区分呢?
我在脚本中是使用find_elements来搜索到所有符合要求的元素,此函数返回的是一个列表,然后再使用下标来定位到具体的输入框。
对于每个输入框具体对应下标值是多少,可以在浏览器中的console中,输入document.getElementsByClassName(“el-input__inner”)回车查看,具体如何操作可继续往下看。
然后将鼠标放在上方输出结果上,就可以看到页面上对应的输入框高亮显示了,例如下方将鼠标放在了下标2上,密码输入框高亮显示。所以要定位到密码输入框代码应该这样写:self.driver.find_elements(By.CLASS_NAME, “el-input__inner”)[2]。
对于登录按钮定位,他的class值为:el-button el-button–primary,存在多个字符串,如果直接使用class方法定位,是定位不到该元素,此时可使用CSS_SELECTOR的方法定位:self.driver.find_element(By.CSS_SELECTOR, “.el-button.el-button–primary.send”),直接将class每一个字符串前加.且将空白符去掉。
3.点击个人中心进入个人信息页:
从以上两张图片中,可以看出当下拉框出现时,元素中的style属性值发生了改变,而我们在代码中可以通过修改改属性值来达到让下拉框出现的效果。
修改style属性值,这里需要使用到js代码:
person_center = self.driver.find_element(By.CSS_SELECTOR, ".avatar.abs")
# js代码,修改属性值
# 修改之前的是display: none;
js = "arguments[0].style = 'display: True;';" # 赋值为True,下拉框出现
# 执行js
self.driver.execute_script(js, person_center)
元素定位语句的书写也可以通过在元素html上右键选择copy,根据自己的定位方法选择需要copy的内容。例如在代码里登录按钮的定位就是使用该方法copy 的selector。
4.进入个人信息页之后,对每个信息进行修改:
下面会具体说一下性别、生日、当前职业、所在地区、职业方向元素的操作方法。也是本人在整个过程中花费额比较多时间的地方。
(1)性别选择:
观察选中的性别和未被选中的性别的属性值上的区别:
分析出选中和未被选中的性别上的区别,接下来就是研究在代码中如何修改这些属性值了,需要使用到js代码来进行修改:
# 先将所有的class值el-radio找出来
sexs = self.driver.find_elements(By.CLASS_NAME, "el-radio")
# 1-3随机数选一个,随机选择一个性别,让每一次执行时,性别会发生改变
number = random.randint(1, 3)
k = 1
# 对每一个性别进行遍历
for sex in sexs:
# 如果是k == number,则被选中
if k == number:
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex, 'class', 'el-radio is-focus is-checked')
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex.find_element(By.CLASS_NAME, "el-radio__input"), 'class', 'el-radio__input is-checked')
else:
# 其它的性别也要修改对应的属性值,不然会出现选中的性别有两个
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex, 'class',
'el-radio')
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])",
sex.find_element(By.CLASS_NAME, "el-radio__input"), 'class',
'el-radio__input')
k = k + 1
(2)生日:
对于日历控件的操作,可以将其中对应的readonly属性值去掉,也是执行js代码的方式进行remove。
如果在浏览器上直接删除readonly属性值,发现生日框可以直接输入内容了:
birthday = self.driver.find_elements(By.CLASS_NAME, "el-input__inner")[4]
# 移除readonly标签值,让日历元素可以直接输入
js = "document.getElementsByTagName('input')[8].removeAttribute('readonly')" # 具体下标值可最开始定位密码输入框是一样的方法
self.driver.execute_script(js)
# 清理原有的旧数据
birthday.clear()
birthday.send_keys("1996-12-21")
birthday.send_keys(Keys.ENTER)
(3)当前职业:
如果是通过标签里的某个属性值来定位元素,可以使用css_selector方式定位,具体书写方式即在该属性值外加上[]中括号括起来即可。
定位到当前职业输入框之后点击,使之出现下拉选择框,然后再通过XPATH方式定位到第一个职位并点击选择。
profession = self.driver.find_element(By.CSS_SELECTOR, "[placeholder='请选择职业']")
# 对当前职业输入框点击,使之出现下拉选择框
profession.click()
# 根据XPATH定位到第一个职业并点击
self.driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/ul/li[1]/span").click()
(4)所在地区:
所在地区的操作方式和当前职业的操作方式类似。
# 定位到所在地区输入框
address = self.driver.find_element(By.CSS_SELECTOR, '[placeholder="请选择"]')
# 进行点击,使之出现下拉框
address.click()
# 先定位到下拉框元素
panel = self.driver.find_element(By.CLASS_NAME, "el-cascader-panel")
# 再从下拉框元素继续定位到“市”元素
panel.find_element(By.CSS_SELECTOR, '[role="menu"]').find_element(By.TAG_NAME, "li").click()
# 市下属,同理
panel.find_elements(By.CSS_SELECTOR, '[role="menu"]')[1].find_element(By.TAG_NAME, "li").click()
(5)职业方向:
点击职业方向的时候,会弹窗,然后才能进行选择。本人在代码里的设计思路是当职业方向已经存在有值了,我就不再进行选择,当为空时,则选择弹窗出来的第一个职业方向并点击确认。
如果已经存在职业方向,则不点击“添加感兴趣的职业方向”,进行选择:
如果没有职业方向,则点击并选择第一个职业方向:
通过class=my_job定位到职业方向的父元素,再通过标签值=button定位到职业方向的按钮。
通过class=el-checkbox-button定位到第一个职业方向,并进行点击选择。
然后定位到确定按钮,进行确认。
# 定位到职业方向点击按钮
profession_direction = self.driver.find_element(By.CLASS_NAME, "my-job").find_element(By.TAG_NAME, "button")
# 找出所有的已存在的职业方向的元素
job_num = self.driver.find_element(By.CLASS_NAME, "my-job").find_elements(By.TAG_NAME, "span")
# 根据当前是否已存在职业方向,进行不同的操作
if len(job_num) == 1:
profession_direction.click()
time.sleep(3.0)
self.driver.find_element(By.CLASS_NAME, "el-checkbox-button").click()
time.sleep(1.0)
self.driver.find_element(By.CSS_SELECTOR, ".el-button.deter.el-button--default").find_element(By.TAG_NAME, "span").click()
5.完整代码:
# coding: utf-8
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
import time
import random
class GetPersonalInformation(object):
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(10.0)
self.driver.get("https://www.atstudy.com/login")
pass
def aw_login(self):
self.driver.find_elements(By.CLASS_NAME, "pic-item")[1].click()
self.driver.find_elements(By.CLASS_NAME, "el-input__inner")[1].send_keys("your telephone")
self.driver.find_elements(By.CLASS_NAME, "el-input__inner")[2].send_keys("your password")
self.driver.find_element(By.CSS_SELECTOR, ".el-button.el-button--primary.send").click()
pass
def aw_go_to_pereson_center(self):
person_center = self.driver.find_element(By.CSS_SELECTOR, ".avatar.abs")
# js代码,修改属性值
# 修改之前的是width: 360px;left: 360px;top: 465px;display: none;
time.sleep(3.0)
js = "arguments[0].style = 'display: True;';"
# 执行js
self.driver.execute_script(js, person_center)
self.driver.find_element(By.CSS_SELECTOR, "#__layout > div > div:nth-child(1) > div > div.top_index > div.t_right > div.login > div > div > ul > li:nth-child(2)").click()
time.sleep(3.0)
pass
def aw_modify_personal_information(self):
username = self.driver.find_element(By.CSS_SELECTOR, "#__layout > div > div.u-basic.nuxt_box > div.u-main.web > div.user-center.u-common > ul > li:nth-child(2) > div > input")
username.clear()
username.send_keys("myusername")
sexs = self.driver.find_elements(By.CLASS_NAME, "el-radio")
number = random.randint(1, 3)
k = 1
for sex in sexs:
if k == number:
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex, 'class', 'el-radio is-focus is-checked')
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex.find_element(By.CLASS_NAME, "el-radio__input"), 'class', 'el-radio__input is-checked')
else:
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", sex, 'class',
'el-radio')
self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])",
sex.find_element(By.CLASS_NAME, "el-radio__input"), 'class',
'el-radio__input')
k = k + 1
birthday = self.driver.find_elements(By.CLASS_NAME, "el-input__inner")[4]
# 移除readonly标签值,让日历元素可以直接输入
js = "document.getElementsByTagName('input')[8].removeAttribute('readonly')"
self.driver.execute_script(js)
# 清理原有的旧数据
birthday.clear()
birthday.send_keys("1996-12-21")
birthday.send_keys(Keys.ENTER)
profession = self.driver.find_element(By.CSS_SELECTOR, "[placeholder='请选择职业']")
# 对当前职业输入框点击,使之出现下拉选择框
profession.click()
# 根据XPATH定位到第一个职业并点击
self.driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/ul/li[1]/span").click()
# 定位到所在地区输入框
address = self.driver.find_element(By.CSS_SELECTOR, '[placeholder="请选择"]')
# 进行点击,使之出现下拉框
address.click()
# 先定位到下拉框元素
panel = self.driver.find_element(By.CLASS_NAME, "el-cascader-panel")
# 再从下拉框元素继续定位到“市”元素
panel.find_element(By.CSS_SELECTOR, '[role="menu"]').find_element(By.TAG_NAME, "li").click()
# 市下属,同理
panel.find_elements(By.CSS_SELECTOR, '[role="menu"]')[1].find_element(By.TAG_NAME, "li").click()
# 定位到职业方向点击按钮
profession_direction = self.driver.find_element(By.CLASS_NAME, "my-job").find_element(By.TAG_NAME, "button")
# 找出所有的已存在的职业方向的元素
job_num = self.driver.find_element(By.CLASS_NAME, "my-job").find_elements(By.TAG_NAME, "span")
# 根据当前是否已存在职业方向,进行不同的操作
if len(job_num) == 1:
profession_direction.click()
time.sleep(3.0)
self.driver.find_element(By.CLASS_NAME, "el-checkbox-button").click()
time.sleep(1.0)
self.driver.find_element(By.CSS_SELECTOR, ".el-button.deter.el-button--default").find_element(By.TAG_NAME, "span").click()
personal_introduction = self.driver.find_element(By.CLASS_NAME, "el-textarea__inner")
personal_introduction.send_keys("略略略11111111")
# 保存
self.driver.find_elements(By.TAG_NAME, "button")[4].click()
time.sleep(3.0)
self.driver.close()
pass
if __name__ == '__main__':
getperinfor = GetPersonalInformation()
getperinfor.aw_login()
getperinfor.aw_go_to_pereson_center()
getperinfor.aw_modify_personal_information()