為什麼Selenium點不到元素

為什麼Selenium點不到元素

來自專欄萌新的學習日記18 人贊了文章

為什麼Selenium點不到元素

最近做了許多登陸項目,我會優先選擇使用requests來模擬請求,但是有些參數實在是很難獲取,這個時候我會使用Selenium,也還是遇到了各種坑,也算是見識到了很多的驗證措施。

今天說說如何解決selenium點選不到數據的問題。

等待

這還是最常見的一種情況,推薦最多的是使用顯示等待:

from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Firefox()driver.get("http://somedomain/url_that_delay_loading")try: element = WebDriverWait(driver,10).until( EC.presence_of_element_located((By.ID,"myDynamicElement")) )finally: driver.quit()

這段代碼會等待10秒,如果10秒內找到元素則立即返回,否則會拋出TimeoutException異常。

但是我比較懶,因為time.sleep()可以達到同樣效果。

滑鼠事件

官方把它叫做「行為鏈」。ActionChains可以完成簡單的交互行為,例如滑鼠移動,滑鼠點擊事件,鍵盤輸入,以及內容菜單交互。

click(on_element=None) ——單擊滑鼠左鍵click_and_hold(on_element=None) ——點擊滑鼠左鍵,不鬆開context_click(on_element=None) ——點擊滑鼠右鍵double_click(on_element=None) ——雙擊滑鼠左鍵drag_and_drop(source, target) ——拖拽到某個元素然後鬆開drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個坐標然後鬆開key_down(value, element=None) ——按下某個鍵盤上的鍵key_up(value, element=None) ——鬆開某個鍵move_by_offset(xoffset, yoffset) ——滑鼠從當前位置移動到某個坐標move_to_element(to_element) ——滑鼠移動到某個元素move_to_element_with_offset(to_element, xoffset, yoffset) ——移動到距某個元素(左上角坐標)多少距離的位置perform() ——執行鏈中的所有動作release(on_element=None) ——在某個元素位置鬆開滑鼠左鍵send_keys(*keys_to_send) ——發送某個鍵到當前焦點的元素send_keys_to_element(element, *keys_to_send) ——發送某個鍵到指定元素

深入了解可以參考 blog.csdn.net/huilan_sa

move_to_element_with_offsetclick_and_hold會經常用到破解驗證碼中。

觸摸操作 (TouchAction)

該事件僅僅針對移動端、觸屏版

flick_element(on_element, xoffset, yoffset, speed) # 以元素為起點以一定速度向下滑動scroll_from_element(on_element xoffset yoffset) #以元素為起點向下滑動double_tap(on_element) #雙擊 flick_element(on_element, xoffset, yoffset, speed) #從元素開始以指定的速度移動long_press(on_element)   #長按不釋放move(xcoord, ycoord)   #移動到指定的位置perform()   #執行鏈中的所有動作release(xcoord, ycoord)   #在某個位置鬆開操作scroll(xoffset, yoffset) #滾動到某個位置scroll_from_element(on_element, xoffset, yoffset) #從某元素開始滾動到某個位置tap(on_element) #單擊tap_and_hold(xcoord, ycoord) #某點按住

為什麼要說到移動端,在做登陸時,移動端往往會更加簡單,但是觸屏版的點擊和PC端時完全不同的,點擊與按住時不同的。

在某個項目我換成TouchAction後,神奇的發現,註冊不再需要處理驗證碼了,真是太棒了。

使用js

當你使用瀏覽器已經找到該元素,使用click()方法但是不起作用時,這個時候建議嘗試js,例如在我的主頁 zhihu.com/people/cuishi,點擊 「查看詳細資料」

js = document.getElementsByClassName("Button ProfileHeader-expandButton Button--plain")[0].click();driver.execute_script(js)

你可以先在控制台調試

js通常可以解決絕大多是問題,如果還是解決不了,那你可能和我遇到了同樣的問題,比如說,我在處理某移動端網站登陸,處理如下驗證碼時,我會使用到move_to_element_with_offset,該方法是「移動到距某個元素(左上角坐標)多少距離的位置」。

計算出坐標後,會調用該方法,如action.move_to_element_with_offset(element, width, height).click().perform(),然而實際上問題並沒有這麼簡單,多次點擊失效。具體的有時間再說。

實用方法

提取selenium的cookies

介紹把selenium的cookies船體給requests使用的方法:

cookies = driver.get_cookies()s = requests.Session()for cookie in cookies: s.cookies.set(cookie[name], cookie[value])

How do I load session and cookies from Selenium browser to requests library in Python?

元素截圖方法

from selenium import webdriverfrom PIL import Imagefox = webdriver.Firefox()fox.get(https://stackoverflow.com/)# now that we have the preliminary stuff out of the way time to get that image :Delement = fox.find_element_by_id(hlogo) # find part of the page you want image oflocation = element.locationsize = element.sizefox.save_screenshot(screenshot.png) # saves screenshot of entire pagefox.quit()im = Image.open(screenshot.png) # uses PIL library to open image in memoryleft = location[x]top = location[y]right = location[x] + size[width]bottom = location[y] + size[height]im = im.crop((left, top, right, bottom)) # defines crop pointsim.save(screenshot.png) # saves new cropped image

selenium cannot screenshot a web element

最後推薦一個神器 appium/python-client

至於驗證碼部分,現在主要還是靠第三方工具,並沒有自己嘗試機器學習等方法處理。


推薦閱讀:

PyStarTrek
Numpy之Meshgrid函數介紹
一個完整的機器學習項目在Python中的演練(一)
《Python之禪》事件之你們想要的實錘
Python(4)-24點小遊戲計算

TAG:Selenium | 爬蟲計算機網路 | Python |