[Python爬蟲] Selenium實現自動登錄163郵箱和Locating Elements介紹

一. Selenium自動登錄

代碼如下所示:

[python] view plaincopy

  1. fromseleniumimportwebdriver
  2. fromselenium.webdriver.common.keysimportKeys
  3. importtime
  4. #模擬登陸163郵箱
  5. driver=webdriver.Firefox()
  6. driver.get("http://mail.163.com/")
  7. #用戶名密碼
  8. elem_user=driver.find_element_by_name("username")
  9. elem_user.send_keys("15201615157")
  10. elem_pwd=driver.find_element_by_name("password")
  11. elem_pwd.send_keys("********")
  12. elem_pwd.send_keys(Keys.RETURN)
  13. time.sleep(5)
  14. assert"baidu"indriver.title
  15. driver.close()
  16. driver.quit()

運行結果如下圖所示,自動打開Firefox瀏覽器並輸入用戶名和密碼實現郵箱登錄。

代碼非常簡單,其中的原理也很簡單:通過driver訪問Firefox瀏覽器及URL,同時find_element_by_name找到網頁HTML源代碼中對應的值並填充,最後調用Keys實現模擬操作鍵盤Keys.RETURN實現。該斷言結果是不存在的,主要是用於防止關閉瀏覽器。 同時輸入用戶名或密碼錯誤會提示,其實就是瀏覽器。

原理解釋 兩年前在學習C#網路編程時,我成寫過Winform自動訪問163郵箱的文章: C# 網路編程之網頁自動登錄 (一).使用WebBrower控制項模仿登錄 通過對比,Python簡短高效的優勢就顯示出來的,其中163郵箱登錄界面HTML源碼也沒有修改和修復過,這是我意料之外的。 其中通過查找該登錄頁面發現用戶名Id為「idInput」,密碼Id為「pwdInput」,登錄按鈕ID為「loginBtn」。如圖id和name: <input class="" tabindex="1" title="請輸入帳號"id="idInput" name="username" type="text" value="".. <input class="" tabindex="2" title="請輸入密碼" id="pwdInput" name="password" type="password" /> <button id="loginBtn" class="" type="submit">登 錄</button> 如下圖所示一目了然:

這部分文章雖然簡單,但是作為基礎文章在合適不過了,同時通過webdriver的driver.find_element_by_name引出下面的基礎知識介紹,畢竟實踐例子才是學習Selenium的動力源泉。 同樣下面這段代碼可實現自動登錄CSDN,是不是可以通過它實現暴力破解密碼呢?[python] view plaincopy

  1. fromseleniumimportwebdriver
  2. fromselenium.webdriver.common.keysimportKeys
  3. importtime
  4. driver=webdriver.Firefox()
  5. driver.get("https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn")
  6. elem_user=driver.find_element_by_name("username")
  7. elem_user.send_keys("Eastmount")
  8. elem_pwd=driver.find_element_by_name("password")
  9. elem_pwd.send_keys("********")
  10. elem_pwd.send_keys(Keys.RETURN)
  11. time.sleep(5)
  12. assert"baidu"indriver.title
  13. driver.close()
  14. driver.quit()

二. Locating Elements介紹 PS:第一次上傳翻譯博文,如果有錯誤還請見諒! 官網地址:http://selenium-python.readthedocs.org/locating-elements.html 這裡有各種策略用於定位網頁中的元素(locate elements),你可以選擇最適合的方案,Selenium提供了一下方法來定義一個頁面中的元素:

  • find_element_by_id
  • find_element_by_name
  • find_element_by_xpath
  • find_element_by_link_text
  • find_element_by_partial_link_text
  • find_element_by_tag_name
  • find_element_by_class_name
  • find_element_by_css_selector
  • 下面是查找多個元素(這些方法將返回一個列表):

  • find_elements_by_name
  • find_elements_by_xpath
  • find_elements_by_link_text
  • find_elements_by_partial_link_text
  • find_elements_by_tag_name
  • find_elements_by_class_name
  • find_elements_by_css_selector
  • 除了上面給出的公共方法,這裡也有兩個在頁面對象定位器有用的私有方法。這兩個私有方法是find_element和find_elements,用法示例:[python] view plaincopy

    1. fromselenium.webdriver.common.byimportBy
    2. driver.find_element(By.XPATH,"//button[text()="Sometext"]")
    3. driver.find_elements(By.XPATH,"//button")

    這些都是通過類可獲取的屬性:[python] view plaincopy

    1. ID="id"
    2. XPATH="xpath"
    3. LINK_TEXT="linktext"
    4. PARTIAL_LINK_TEXT="partiallinktext"
    5. NAME="name"
    6. TAG_NAME="tagname"
    7. CLASS_NAME="classname"
    8. CSS_SELECTOR="cssselector"

    1 Locating By Id

    當你知道一個元素的id屬性時使用該功能。有了這個方法,用id屬性值匹配時第一個被定位的元素將被返回。如果沒有元素匹配id值,一個NoSuchElementException異常將會拋出。例如,參考這個頁面源碼:

    [html] view plaincopy

    1. <html>
    2. <body>
    3. <formid="loginForm">
    4. <inputname="username"type="text"/>
    5. <inputname="password"type="password"/>
    6. <inputname="continue"type="submit"value="Login"/>
    7. </form>
    8. </body>
    9. <html>

    表單form元素可以被如下方式定位:[python] view plaincopy

    1. login_form=driver.find_element_by_id("loginForm")

    2 Locating By Name

    當你知道一個元素的name屬性時使用該方法。通過該方法,第一個滿足name屬性值的元素將被匹配返回,如果沒有元素匹配,將拋出一個NoSuchElementException異常。例如,參考下面源碼:

    [html] view plaincopy

    1. <html>
    2. <body>
    3. <formid="loginForm">
    4. <inputname="username"type="text"/>
    5. <inputname="password"type="password"/>
    6. <inputname="continue"type="submit"value="Login"/>
    7. <inputname="continue"type="button"value="Clear"/>
    8. </form>
    9. </body>
    10. <html>

    定位username&password元素方法如下:[python] view plaincopy

    1. username=driver.find_element_by_name("username")
    2. password=driver.find_element_by_name("password")

    在"Clear"按鈕之前會給出"Login"登錄按鈕:[python] view plaincopy

    1. continue=driver.find_element_by_name("continue")

    3 Locating By XPath XPath是用於定位XML文檔中節點的語言。正如HTML可以是XML(XHTML)的一個實現,Selenium用戶可以利用這個強大的語言來跟蹤Web應用程序中的元素。XPath擴展已經超出(以及支持)了按照id或name屬性定位的簡單方法,並開發了各種新的可能,如定位頁面上的第三個複選框(checkbox)。 其中使用XPath的一個主要原因是:當你沒有一個合適的ID或Name屬性來定位你需要查找的元素時,你可以使用XPath去定位這個絕對元素(不建議這樣),或者相對一個有id或name屬性的元素定位。XPath定位器也可以通過其他不止是id和name屬性進行指定元素。 絕對XPath包含定位的所有元素,這些元素從根(HTML)到其結果可能會失敗,只有稍微調整到應用程序。通過找到附近的一個元素的id或name屬性(理想的父元素),你才可以根據之間的關係定位到你追蹤的元素。這是不太可能改變的,並且會使你的測試更加的健壯。例如參考下面這段源代碼:[html] view plaincopy

    1. <html>
    2. <body>
    3. <formid="loginForm">
    4. <inputname="username"type="text"/>
    5. <inputname="password"type="password"/>
    6. <inputname="continue"type="submit"value="Login"/>
    7. <inputname="continue"type="button"value="Clear"/>
    8. </form>
    9. </body>
    10. <html>

    這個表單form元素可能通過如下方法被定位:[python] view plaincopy

    1. login_form=driver.find_element_by_xpath("/html/body/form[1]")
    2. login_form=driver.find_element_by_xpath("//form[1]")
    3. login_form=driver.find_element_by_xpath("//form[@id="loginForm"]")

    [1] 絕對路徑(如果HTML有稍微的改動,就會被破壞) [2] 在HTML中的第一個表單元素 [3] 指定屬性名稱為id且值為loginForm的表單元素 定位username元素的方法如下:[python] view plaincopy

    1. username=driver.find_element_by_xpath("//form[input/@name="username"]")
    2. username=driver.find_element_by_xpath("//form[@id="loginForm"]/input[1]")
    3. username=driver.find_element_by_xpath("//input[@name="username"]")

    [1] 第一個form元素通過一個input子元素,name屬性和值為username實現 [2] 通過id=loginForm值的form元素找到第一個input子元素 [3] 屬性名為name且值為username的第一個input元素 定位"Clear"按鈕元素的方法如下:[python] view plaincopy

    1. clear_button=driver.find_element_by_xpath("//input[@name="continue"][@type="button"]")
    2. clear_button=driver.find_element_by_xpath("//form[@id="loginForm"]/input[4]")

    [1] 屬性名為name其值為continue和屬性名為type其值為button的Input控制項 [2] 屬性id=loginForm的form元素的第四個input子元素 上面這些例子涉及一些基礎知識,更多詳情請參考下面的建議:

  • W3Schools XPath Tutorial
  • W3C XPath Recommendation
  • XPath Tutorial- with interactive examples.
  • 這裡也有幾個非常實用的附加組件,可以幫助發現元素的XPath:

  • XPath Checker- suggests XPath and can be used to test XPath results.
  • Firebug- XPath suggestions are just one of the many powerful features of this very useful add-on.
  • XPath Helper- for Google Chrome
  • 4 Locating Hyperlinks By Link Text 當你知道一個錨標記內使用鏈接文本就使用該方法。通過這個策略,第一個匹配這個link text值的元素將被返回。如果沒有元素匹配這個鏈接文本,將拋出一個NoSuchElementException異常。示例的源代碼如下:[html] view plaincopy

    1. <html>
    2. <body>
    3. <p>Areyousureyouwanttodothis?</p>
    4. <ahref="continue.html">Continue</a>
    5. <ahref="cancel.html">Cancel</a>
    6. </body>
    7. <html>

    這個continue.html鏈接定位的方法如下,partial表示部分匹配:[python] view plaincopy

    1. continue_link=driver.find_element_by_link_text("Continue")
    2. continue_link=driver.find_element_by_partial_link_text("Conti")

    5 Locating Elements By Tag Name 當你想通過tag name(標記名)定位一個元素時可以使用該方法。同樣,第一個給出的tag name元素將被返回,如果沒有匹配的標記名,將拋出一個NoSuchElementException異常。示例的源代碼如下:[html] view plaincopy

    1. <html>
    2. <body>
    3. <h1>Welcome</h1>
    4. <p>Sitecontentgoeshere.</p>
    5. </body>
    6. <html>

    定位heading(h1)元素的方法如下:[python] view plaincopy

    1. heading1=driver.find_element_by_tag_name("h1")

    6 Locating Elements By Class Name 介紹類似,用於通過類屬性名(class attribute name)進行定位一個元素。示例源代碼如下:[html] view plaincopy

    1. <html>
    2. <body>
    3. <pclass="content">Sitecontentgoeshere.</p>
    4. </body>
    5. <html>

    其中元素"p"的定位方法如下:[python] view plaincopy

    1. content=driver.find_element_by_class_name("content")

    7 Locating Elements By CSS Selectors 當你想要通過CSS選擇器語法定位一個元素時,可以使用該方法。它將返回第一個與CSS選擇器匹配的元素,如果沒有匹配CSS選擇器的元素,將返回一個NoSuchElementException異常。實例源代碼如下所示:[html] view plaincopy

    1. <html>
    2. <body>
    3. <pclass="content">Sitecontentgoeshere.</p>
    4. </body>
    5. <html>

    其中元素"p"的定位方法如下:[python] view plaincopy

    1. content=driver.find_element_by_css_selector("p.content")

    Sauce實驗室有非常好的關於CSS選擇器的文檔: Sauce Labs has good documentationon CSS selectors. (By:Eastmount 2015-8-21 下午6點 http://blog.csdn.net/eastmount/)
    推薦閱讀:

    TAG:Python | 郵箱 | 介紹 | 爬蟲 | Elements | 登錄 | 163郵箱 | Selenium | 實現 |