• 爬虫三(模拟登陆)


    1、Selenium工具

    Selenium是ThroughtWorks公司开发的一套Web自动化测试工具,它分为三个组件:

    • Selenium IDE
    • Selenium RC (Remote Control)
    • Selenium Webdriver

    Selenium IDE是firefox的一个插件,允许测试人员录制脚本并回放。

    Selenium RC和Selenium Webdriver是测试框架,提供多种语言的API。不同的是,Selenium Webdriver以一种更底层、更灵活的方式来操作浏览器,并不仅仅使用JavaScript。这样它可以绕开浏览器的沙箱限制,实现Selenium RC不支持的框架、弹出窗口、页面导航、下拉菜单、基于AJAX的UI元素等控件的操作。以及,Selenium Webdriver不需要本地服务器。

    Selenium 1.x版本只包含前两个组件。从2.0开始Webdriver加入其中,主要是来解决https的加密问题。

    2、Webdriver的使用

    在使用之前,不需要下载一个浏览器所对应用的驱动插件,请根据自己不同的浏览器版本进行下载

    链接:https://pan.baidu.com/s/1qZ2LfmW 密码:qixa

    下载以后,并把chromdriver放在google.exe那个当前目录下面

    import os
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys

    chromedriver = "C:Program Files (x86)GoogleChromeApplicationchromedriver.exe"
    os.environ["webdriver.chrome.driver"] = chromedriver
    driver = webdriver.Chrome(chromedriver)

    driver.get("http://www.python.org")
    driver.quit()

    3、Webdriver定位元素的八种方式

    在UI层面的自动化测试开发中,元素的定位与操作是基础,也是经常遇到的困难所在。webdriver提供了8种定位:

    ①、id定位:find_element_by_id("id值");id属性是唯一的

    • driver.find_element_by_id("loginName").clear()     #用户名输入框的id属性
    • driver.find_element_by_id("loginName").send_keys("admin")
    • driver.find_element_by_id("pwdTip").send_keys(Keys.TAB)    #密码输入框的id属性
    • driver.find_element_by_id("pwdTip").send_keys("111111")

    ②、name定位:元素的名称,find_element_by_name("name值");name属性值在当前页面可以不唯一

    • driver.find_elements_by_name("PeriodName")[1].click()    #选择学段:初中
    • driver.find_elements_by_name("SubjectName")[0].click()   #选择学科:语文

    find_elements_by_name("PeriodName")    #是因为当前页面有一组radiobutton的name值是PeriodName,所以可以用定位一组元素的方法findElements,定位出来的是结果一个list

    ③、class定位:元素的类名,find_element_by_class_name("class值")

    •  driver.find_elements_by_class_name("u-btn-levred")[0].click()     #选择年级:七年级

    ④、tag定位:页面html文档下的各种标签,find_element_by_tag_name("input")

    tag往往用来定义一类功能,所以通过tag识别某个元素的概率很低。任意打开一个页面,都会发现大量的<div>、<input>、<a>等tag,所以tag name定位很少用

    ⑤、link定位:专门用来定位文本链接,find_element_by_link_name("text")

    •  driver.find_element_by_link_text(u"退出").click()     #页面右上方的一些个人操作,比如退出、个人中心、消息通知等

    ⑥、partial link定位:是对link定位的一种补充,当链接上的文本内容比较长的时候,可以取文本的一部分进行定位,当然这部分可以唯一地标识这个链接

    ※注:以上的方式稍有局限,且经常页面没有id,name这些属性值,class name重复性较高,link定位有针对性,所以Xpath与Css定位更灵活些

    ⑦、XPath定位:find_element_by_xpath("");有多种定位策略,用FirePath插件自动生成的涵盖以下几种方式

       1)绝对路径定位:对于没有id,name、classname不好定位的,这也是我最常用的,因为可以通过Firefox的FirePath插件可以方便的获取到xpath值

       2)利用元素属性定位:

       find_element_by_xpath(".//*[@id='Title']"),这里是用的id,也可以用元素其他能够唯一标识的属性,不局限于id、name、class这些;*代表的是标签名,不指定时就可以用*代替

       3)层级与属性结合:下图中就是这种

       4)使用逻辑运算符

     

    •  driver.find_element_by_xpath(".//*[@id='divword']/input[7]").click()     #登录
    • driver.find_element_by_xpath("html/body/div[4]/div/div[2]/div/div[3]/a[1]").click()     #个人页面的发布课程操作

       5)XPath的相关定义:

    XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。 

    绝对路径: 根元素开始,及html开始用/     

    相对路劲: 任意符合条件的元素 //

    查找页面上所有的input元素://input

    查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)://form[1]/input

    查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)://form[1]//input

    查找页面上第一个form元素://form[1]

    查找页面上id为loginForm的form元素://form[@id='loginForm']

    查找页面上具有name属性为username的input元素://input[@name='username']

    查找页面上id为loginForm的form元素下的第一个input元素://form[@id='loginForm']/input[1]

    查找页面具有name属性为contiune并且type属性为button的input元素://input[@name='continue'][@type='button']

    查找页面上id为loginForm的form元素下第4个input元素://form[@id='loginForm']/input[4]

    ⑧、CSS定位(薄弱,用的很少,但很强大,比xpath简洁灵活):使用选择器来为页面元素绑定属性,可以灵活地选择控件的任意属性;find_element_by_css_selector("");同样也可以用FirePATH生成css哟!

       1)通过class属性定位:点号(".")表示通过class属性定位

    • <input class="u-btn mart5" type="submit" onclick="return User.check()" value="登录">
    • driver.find_element_by_css_selector(".u-btn.mart5").click()

       2)通过id属性定位:("#")表示通过id定位元素

    • driver.find_element_by_css_selector("#loginName")

       3)通过其他属性定位:("[ ]"),中括号里的属性可以唯一标识这个元素就可以;属性的值可以加引号,也可以不加

    • <input class="u-btn mart5" type="submit" onclick="return User.check()" value="登录">
    • driver.find_element_by_css_selector("[type=submit]").click()

       4)组合定位

    平时使用生成的xpath,id,name,classname这些比较多,今天根据最近这段时间的实践,并参照书上整理了下,发现原来XPath和Css下还有这么多方式,顺便拿最近一些代码试验了下,有些简单的css定位能够成功,有的Firepath生成的并不可用,一些组合定位还需要再研究,是有些难度的。最后记录一种定位方式,更接近底层实现方式的定位,But书上说webdriver更推荐前面那些写法,为毛捏?

    ⑨、用By定位元素

      除find_element_by_***这种方式,还有另一套写法,也就是统一调用find_element()方法,两个参数,第一个参数是定位的类型,由By提供;第二个参数是定位的具体值

    from selenium.webdriver.common.by import By     #使用By这种定位前要将By类导入

    find_element(By.ID,"loginName")
    find_element(By.NAME,"SubjectName")
    find_element(By.CLASS_NAME,"u-btn-levred")
    find_element(By.TAG_NAME,"input")
    find_element(By.LINK_TEXT,"退出")
    find_element(By.PARTIAL_LINK_TEXT,"退")
    find_element(By.XPATH,".//*[@id='Title")
    find_element(By.CSS_SELECTOR,"[type=submit]")

    4、控件操作

    ①、输入框:

    • element.clear()     清空输入框数据
    • element.sendkeys(“username”)      发送数据
    • element.text         获取文本的值

    ②、按钮:

    • element.click()

    ③、表单提交

    • element.submit()

    ④、单选和多选框

    • element.clear()
    • element = browser.find_elements_by_id(' checkbox')

    ⑤、选择某个单选项:

    • element.click()

    5、常用方法

    • browser.get_cookies()     #获取cookie相关内容
    • browser.title        #头名字
    • browser.close()      #关闭
    • forward()       #前进,browser.foeward()
    • back()      #后退,browser.back()
    • refresh()      #刷新,browser.refresh()
    • current_url      #返回当前页面url,browser.current_url

    6、登录12306

    from selenium import webdriver

    import random
    import time

    def randomSleep(minS, maxS):
    time.sleep((maxS - minS) * random.random() + minS)
    browser = webdriver.Chrome(r"C:Program Files (x86)GoogleChromeApplicationchromedriver.exe")

    url = "https://kyfw.12306.cn/otn/login/init"

    browser.get(url=url)
    print(browser.find_element_by_id("username").text)
    browser.find_element_by_id("username").clear()
    browser.find_element_by_id("username").send_keys("974644081@qq.com")
    randomSleep(2, 5)
    browser.find_element_by_id("password").send_keys(“xxxxxxxxx")
    randomSleep(1, 4)
    time.sleep(6)
    browser.find_element_by_id("loginSub").click()
    randomSleep(2, 5)
    print(browser.get_cookies())
    browser.quit()

    7、登录京东

    from selenium import webdriver

    import random
    import time

    def randomSleep(minS, maxS):
    time.sleep((maxS - minS) * random.random() + minS)
    browser = webdriver.Chrome(r"C:Program Files (x86)GoogleChromeApplicationchromedriver.exe")
    # browser = webdriver.Chrome()

    # Home
    browser.get("https://passport.jd.com/new/login.aspx")

    # Login by username and password
    randomSleep(1, 2)
    browser.find_element_by_xpath("//a[@clstag='pageclick|keycount|201607144|2']").click()
    # browser.find_element_by_tag_name("pageclick|keycount|201607144|2").click()

    # Username and password
    randomSleep(1, 2)
    browser.find_element_by_id("loginname").send_keys(“xxxxxxx")
    print(browser.find_element_by_id("loginname").text)

    randomSleep(1, 3)
    browser.find_element_by_id("nloginpwd").send_keys(“xxxxxx")

    # Submit, wait for a long time
    randomSleep(5, 10)
    browser.find_element_by_id("loginsubmit").click()


    print(browser.get_cookies())
    randomSleep(3, 5)

    browser.quit()

    8、思考

    在centos等linux服务器上,如果通过无界面的方式进行登录呢

     

  • 相关阅读:
    java.lang.IllegalArgumentException: No converter found for return value of type: class XXX.XXXX
    关于websocket集群中不同服务器的用户间通讯问题
    JavaScript中 location.host 与 location.hostname 的区别
    Spring在代码中获取bean的几种方式
    在websocket中怎么样注入service类
    阿里云上部署kafka--遇到的坑
    linux系统部署Java程序获取ip时报Caused by: java.net.UnknownHostException: XXXXXXXXXX: XXXXXXXXXX: Name or service not known
    解决bash: mysql: command not found 的方法
    Nginx的启动、停止与重启
    Java8:Lambda表达式增强版Comparator和排序
  • 原文地址:https://www.cnblogs.com/Jweiqing/p/9189457.html
Copyright © 2020-2023  润新知