selenium+python實現1688登錄 —— iframe中元素獲取


selenium+python實現1688登錄 —— iframe中元素獲取

1. 背景

  • 在1688網站登錄時,無法通過 browser.find_element_by_xpath 直接獲取到用戶名和密碼的輸入框。
  • 從網頁源代碼分析,發現這個網頁是一個iframe嵌套的模式,所以按照傳統的方式無法定位到表單元素。

2. 環境

  • python 3.6.1
  • 系統:win7
  • IDE:pycharm
  • 安裝過chrome瀏覽器
  • 配置好chromedriver
  • selenium 3.7.0

3. 分析過程

3.1. 進入1688登錄頁面,分析網頁結構。

這里寫圖片描述

這里寫圖片描述

  • 也就是說,登錄框是以子頁面(iframe)的方式嵌入在主頁面中的。
  • 所以按照以下的方式是無法獲得“密碼登錄”這個超鏈接的。
# 尋找使用用戶名和密碼登陸的鏈接,並點擊
links = browser.find_elements_by_tag_name("a")
for link in links:
# print(f"linkText1 = {link.text}, link = {link}")
if link.text == '密碼登錄':
link.click()
break
  • 需要在此之前將focus由default content轉到這個frame:
# 切換到登錄框frame
# 這種是網頁中有frame嵌套,而且沒有標記,不知道frame的name,通過源代碼,知道是第一個iframe
browser.switch_to.frame(browser.find_elements_by_tag_name("iframe")[0])
  • 切換到frame的方式(browser.switch_to.frame)有三種,引用源代碼中的注釋:
"""
Switches focus to the specified frame, by index, name, or webelement.

:Args:
- frame_reference: The name of the window to switch to, an integer representing the index,
or a webelement that is an (i)frame to switch to.

:Usage:
driver.switch_to.frame('frame_name') # iframe標簽的name屬性
driver.switch_to.frame(1)
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
"""

3.2. 點擊密碼登錄,分析網頁結構。

  • 此時網頁結構並未發生變化:
    這里寫圖片描述
# 輸入用戶名和密碼
userNameInput = browser.find_element_by_xpath("//input[@name='TPL_username']")
userNameInput.clear()
userNameInput.send_keys(userName)

userPassword = browser.find_element_by_xpath("//input[@name='TPL_password']")
userPassword.clear()
userPassword.send_keys("ancode2017")
time.sleep(5)
# 敲enter鍵
userPassword.send_keys(Keys.RETURN)
time.sleep(30)
  • 此時大概率情況下,會直接通過。小概率會進行滑塊驗證碼 + 手機短信驗證。

3.3. 進入短信驗證碼頁面,分析網頁結構。

  • 此時網頁結構又發生了變化:
    這里寫圖片描述

  • 分析源碼可以看到手機驗證輸入框處於 Main ——> iframe ——> iframe兩層嵌套之內。

  • 所以,需要再次改變focus
# 首先切換到新的 frame,這個是原來登錄frame下又嵌套了一層frame
# 當前browser的focus已經是中間層的frame,所以這里只要再switch一層即可
browser.switch_to.frame(browser.find_elements_by_tag_name("iframe")[0])
# 尋找發送手機驗證碼按鈕
messageSendButton = browser.find_element_by_xpath("//button[@id='J_GetCode']")
print(f"messageSendButton = {messageSendButton}")
messageSendButton.click()

# 手動獲得手機驗證碼,並輸入到程序中
messageConfirm = input("Enter your message confirm:")
print(f"messageConfirm = {messageConfirm}")

# 輸入手機驗證碼
messageConfirmInput = browser.find_element_by_xpath("//input[@id='J_Checkcode']")
messageConfirmInput.clear()
messageConfirmInput.send_keys(messageConfirm)

# 提交
submit = browser.find_element_by_xpath("//button[@type='submit']")
submit.click()
# 進入頁面
time.sleep(60)

4. 總結

  • 如果一個頁面只有一個head, 一個body,那么可以直接使用browser.find_element_by_xxxx( )查找頁面中的任何一個元素。
  • 假如頁面中存在< iframe ………….. /iframe>的使用,使得一個html頁面中包含多個子html頁面。
    • 在這種情況下,使用browser.find_element_by_xxxx( )查找頁面某個元素,如果元素是屬於主html的,那么可以查找到。
    • 如果該元素是屬於某個子的< iframe ………….. /iframe>下,使用browser.find_element_by_xxxx( )獲取頁面元素會失敗。要想成功,首先要弄清楚該元素所屬的frame的,並將focus切換到該frame
  • 方法是:先使用browser.switch_to.frame( ) , 然后再使用 browser.find_element_by_xxxx( )查找元素。
  • 操作完以后,如果想返回主頁面,那么使用:browser.switch_to.default_content( )
  • 操作完以后,如果想返回上一級frame,那么使用:browser.switch_to.parent_frame( )

5. 代碼


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com