# coding:utf-8
'''
4.1.1 id定位
find_element_by_id('kw')
find_element_by_id('su')
find_element_by_id()方法通过id属性来定位元素
4.1.2 name定位
find_element_by_name('wd')
4.1.3 class定位
find_element_by_class_name('s_ipt')
4.1.4 tag定位
find_element_tag_name()
4.1.5 link定位
find_element_by_link_text('新闻')
4.1.6 partial link定位
一个很长很长很长的文本链接
定位如下:
find_element_by_partial_link_text('一个很长的')
find_element_by_partial_link_text('文本链接')
find_element_by_partial_link_text()方法通过元素标签对之间的部分文本信息来定位元素
4.1.7 XPath定位
XPath是一种在XML文档中定位元素的语言。
绝对路径
find_element_by_xpath('/html/body/div[2]/div/div[4]/div/form/span/input')
利用元素属性定位
find_element_by_xpath('//input[@id = 'kw'')
//表示当前页面某个目录下,input表示定位元素的标签名,[@id = 'kw']表示这个元素的
属性值等于kw。
-如果不想指定标签名,也可以用星号(*)代替
-find_element_by_xpath('//*[@class = 'bg_s_ipt_wr']/input')
使用逻辑运算符
-可以使用开发者管理工具,获取XPath路径
//*[@id="auto-id-1540179517963"]
4.1.8 CSS定位
-通过class属性定位
find_element_by_css_selector('.s_ipt')
-通过ID属性定位
find_element_by_id_selector('#kw')
-# 表示通过ID属性定位元素
通过标签名定位元素
find_element_by_css_selector('input')
通过父子关系定位
find_element_by_css_selector('span>input')
通过属性定位
find_element_by_css_selector('name = 'kw'')
-组合定位
find_element_by_css_slector('span.bg s_ipt_wr > input.s)ipt')
意思是,有一个父元素,他的标签名叫span,他有一个class属性值bg s_ipt_wr
他有一个子元素,叫input,且其class属性值叫s_ipt。
4.1.9 用By定位元素
WebDirver还提供了另外一套写法,即统一调用find_element(),通过By开声明定位的方法,
并且传入对应定位方法的定位参数,具体如下:
find_element(By.ID, 'kw')
find_element(By.NAME, 'wd')
find_element(By.CLASS_NAME, 's_ipt')
find_element(By.TAG_NAME, 'input')
find_element(By.LINK_TEXT, '新闻')
find_element(By.PARTIAL_LINK_TEXT, '新')
find_element(By.XPATH, '//*[@class = 'bg s_btn']')
finf_element(By.CSS_SELECTOR,'span.bg s_btn_wr > input#su')
find_element()方法只用于定位元素,他需要两个参数,第一个参数是定位的类型,
第二个参数是定位的具体方式,在使用By之前需要将By类导入:
from selenium.webdriver.common.by import By
'''
# 等待iframe加载,直到获取到标签
# WebDriverWait(self, driver, timeout, poll_frequency = POLL_FREQUENCY,
# ignired_exception = None)
'''
其中:
driver: 传入WebDriver实例,即我们上例中的driver
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛
出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,
则中断代码,抛出异常。默认只有NoSuchElementException。
即:
WebDriverWait(driver, 超时时长, 调用频率,
忽略异常).until(可执行方法, 超时时返回的信息)
'''
import logging
import os
import datetime
import traceback
from threading import Thread, Lock
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
class Login():
def __init__(self):
self.browser = webdriver.Chrome()
# self.url = ''
def login_Log(self):
# 组合日志文件名(当前文件名+当前时间).比如:case_login_success-20150817192533
basename = os.path.splitext(os.path.basename(__file__))[0]
print(basename)
logFile = basename + "-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S")+".log"
logging.basicConfig(filename = logFile) # 将日志记录到文件中
s = traceback.format_exc()
logging.error(s) # 记录错误的日志
self.browser.get_screenshot_as_file("./"+logFile+"-error.png") # 截取登录的图片
def login(self, username, pw, url):
self.browser.get(url)
print('Before login ------------------')
# 打印当前页面title
title = self.browser.title
print(title)
# 打印当前页面URL
now_url = self.browser.current_url
print(now_url)
# 执行邮箱登录
element = WebDriverWait(self.browser, 30, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='x-URS-iframe']")))
# 切换标签
self.browser.switch_to.frame('x-URS-iframe')
# 定位到账号框
# inputText = browser.find_element(By.XPATH, '//*[@id = 'accound-box']//div[2]//input')
try:
# 输入账号和密码
inputText = self.browser.find_element(By.XPATH,"//*[@id='account-box']//div[2]//input")
inputText.send_keys(username)
password = self.browser.find_element(By.XPATH, "//*[@id='login-form']//div//div[3]//div[2]//input[2]")
password.send_keys(pw)
# 模拟回车键
password.send_keys(Keys.ENTER)
time.sleep(3)
# 再次打印当前页面的title和URL
# 打印当前页面title
title = self.browser.title
print(title)
# 打印当前页面URL
now_url = self.browser.current_url
print(now_url)
urlname = 'WelcomeModule%******
currUrl = self.browser.current_url
# if currUrl == 'https://mail.163.com/js6/main.jsp?sid=mByNJRhTjHKgSBtCopTTboGboPTwORDC&df=email163#module=welcome.WelcomeModule%7C%7B%7D':
if urlname in currUrl :
print('恭喜你,登陆成功!') # "https://mail.163.com/js6/main.jsp?sid=WCVcOrFyJRbWJvtQTzyyWZQswpQsyPZz&df=mail163_letter#module=welcome.WelcomeModule%7C%7B%7D"
else:
# s = Login()
# nullName(self)
print('登录失败!!!')
self.login_Log()
self.browser.quit()
except:
print('登录失败')
# 跟踪日志
self.login_Log()
time.sleep(10)
def logout(self, browser):
# self.browser.find_element_by_link_text('退出').click()
# time.sleep(50)
self.browser.quit()
更新了一下:
更新了打印网页一些信息的功能,以及登录失败退出的功能。
其中,判断登录失败的方法,一个网友给的方法是:
# if currUrl == 'https://mail.163.com/js6/main.jsp?sid=mByNJRhTjHKgSBtCopTTboGboPTwORDC&df=email163#module=welcome.WelcomeModule%7C%7B%7D':
但是,每次登录后的URL都是变化的,所以通过这一条进行判断是行不通的。通过观察发现,URL的后几位的字符串是保持不变的,应该是登录名一类的,可以判断是否是这个登录名。】
# cond:utf-8
from attributeAddress import Login
from selenium import webdriver
# from simulate163 import Login
username = '999999999999'
pw = 'ra88888888'
url = 'https://mail.163.com/'
Login().login(username, pw, url)
这样就可以成功啦!