【Python成長之路】Boss直聘爬蟲第2彈:selenium找不到元素的常見問題

哈嘍大家好,我是鵬哥。

 

今天繼續上週的主題是 —— boss直聘網站的爬蟲。

 

~~~上課鈴~~~

 

盜墓筆記·十年人間李常超(Lao乾媽) - 盜墓筆記·十年人間

1

寫在前面

上一篇文章講的如何破解boss直聘網站的滑塊認證:

【Python成長之路】破解Boss直聘網站滑塊驗證

這個方法對CSDN、淘寶等網站都是有效的。後來看到有人留言說,爲什麼不用cookies?這樣就直接避免了賬號密碼認證。嗯,說的有道理。因此我在補充這第2彈時,也補充下cookies保存、加載的說明。

當然重點還是記錄下我在爬蟲boss網站時,遇到的幾類selenium找不到元素的原因及對應的規避方法。

2

cookies免賬號驗證

cookies信息的獲取,在selenium庫中有現成的方法可以調用:driver.get_cookies();而加載網頁時,只需要再調用driver.add_cookie()即可。具體代碼實現可以參考以下示例代碼:​​​​​​​

# coding=utf-8# @公衆號 : "鵬哥賊優秀"# @Date : 2020/3/29# @Software : PyCharm # @Python version: Python 3.7.2
from selenium import webdriverimport jsonimport time
class Cookies:    def __init__(self, driver):        self.driver = driver
    def save_cookies(self):        cookies = self.driver.get_cookies()        json_cookies = json.dumps(cookies)        # 保存cookies,方便後續加載使用        with open('cookies.json', 'w', encoding='utf-8') as f:            f.write(json_cookies)
    def add_cookies(self):        # 加載前先清除之前的cooikes,防止影響        self.driver.delete_all_cookies()        with open('cookies.json', 'r', encoding='utf-8') as f:            list_cookies = json.loads(f.read())        for i in list_cookies:            self.driver.add_cookie(i)

if __name__ == "__main__":    url = 'https://www.zhipin.com/job_detail/?ka=header-job'    option = webdriver.ChromeOptions()    option.add_experimental_option('excludeSwitches', ['enable-automation'])    driver = webdriver.Chrome('chromedriver.exe',options=option)    driver.maximize_window()    driver.get(url)    time.sleep(3)    cookies = Cookies(driver)    # # 保存cookies    # cookies.save_cookies()    # 加載cookies    cookies.add_cookies()    driver.get(url)    time.sleep(3)

整體代碼還 是比較簡單易理解的,與之前selenium使用的區別僅在於:打開網頁後再重新加載cookies並刷新,這樣就實現了cookies免賬號認證的功能。

 

3

常見selenium找不到元素的情況

下面我就彙總下幾類常見selenium找不到元素的情況,及對應的解決方法。

情況1:find_element_by_XX()方法使用不正確

selenium最簡單的元素查找方法是通過id、name、class_name:​​​​​​​

    driver.find_element_by_class_name()    driver.find_element_by_name()    driver.find_element_by_id()

只要網頁上有明確的這三個字段,基本不會找錯。但是很多時候網頁元素並不能通過以上方法實現,如<div class="info primary">類class_name中有空格即需要其他方法來查找了;又如下方這個元素即沒 id,也沒class_name,就不好找了。

<a href="/gongsi/dbc073226b21d2830Hx93d67.html" title="塗鴉智能招聘" ka="search_list_company_2_custompage" target="_blank">塗鴉智能</a>

因此我就想到了萬能的元素查找方法:driver.find_element_by_xpath()但是由於自己對html不熟悉,經常出現找不到元素。這裏教大家一個小技巧:通過F12的查找,將你自己的xpath代碼輸入進行查找。

如上圖,可以在查找對話框中將自己的xpath輸入,如果是正確的話就能找到自己的相應元素。通過這個小技巧可以快速避免自己的代碼。

 

如果說第1種情況是由於自己代碼功底不足,那接下去的幾類情況就是網站反爬蟲導致的。

 

情況2:網頁元素設置成不可見

一般我們通過selenium打開網站後,自己是能看到想要的內容,但是代碼卻一直報找不到元素,如下圖:

我要找這個“項目經理”元素,卻就是找不到。這 裏我們要仔細看下html代碼了。看到沒?網站設置了當前界面爲style='display:none',就是這個style導致了selenium找不到。

作爲常見的反爬蟲方法,解決方法也很簡單,只需要將style設置爲可見即可,規避方法如下:​​​​​​​

    js = "document.getElementsByClassName('job-tab')[0].style.display='block';"    driver.execute_script(js)

 

情況3:iframe內嵌表單切換

有時候即使你已經設置了style可見,發現還是找不到元素,這是爲什麼?先別急,我們再仔細看看html代碼。

看到沒?你會發現你要找的元素在一個新的iframe。怎麼理解呢?相當於你開始進入的是房子的大門,但是你要的元素卻是在房子裏的一個小房間裏,所以你要走進這個小房間。

規避方法:找到對應iframe元素,然後switch_to.frame

driver.switch_to.frame(driver.find_element_by_name('zhipinFrame'))

如果最後要切換之前的iframe,可以用switch_to.default_content()跳回最外層的頁面

一般來說,論文留言板塊都會採用iframe內嵌表單,所以可以關注下。

 

情況4:網頁元素未加載完成

我一開始在爬蟲Boss時,發現一樣的driver.find_element_by_xpath('ul[{}]'.format(i))時,有時候能找到元素,有時候卻報錯,提示找不到元素。

最後從我自己的試驗來看,應該是用xpath查找時,對應元素還未加載完成,導致偶現的找不到元素。

規避方法:time.sleep(3)。

這裏我說下,有些博客裏說只要等0.5S或者 1S就夠了,但是boss時間不夠的,sleep(1)仍然會出現找 不到的現象。

 

情況5:界面元素加載屬於懶加載

很多網站在顯示內容時,採用了懶加載,如boss顯示牛人信息時,滑到底部需要等一下才會加載出新的內容。但是如果用selenium打開網站,能爬取的元素只有當前展示內容,因此需要模擬用戶進行滾輪滑動。​​​​​​​

js = 'var action=document.documentElement.scrollTop=50000'driver.execute_script(js)

這個滾輪加載的動作可以在查找元素前做,這樣第一次查找時就可以爬取到更多內容。(可以寫個循環即可以多滾動幾頁了)

 

情況6:能找到對應元素,卻無法點擊

上面講到了滾輪加載更多的元素,但是也會出現一個情況。如 我要點擊“立即溝通”這個按鈕,我能通過find_element_by_xx找到,但是報沒此元素因此點擊不了。

這裏是因爲當前界面中的確無此元素,而是當前界面的前幾頁。

規避方法:

這裏我採用的是循環向上翻頁,並在每頁嘗試查找此元素。​​​​​​​

    for  i in range(5):        try:            # 查找此元素並點擊            driver.find_element_by_name('test').click()        except:            # 向上翻頁            js = 'var action=document.documentElement.scrollTop=0'            driver.execute_script(js)            continue

 

5

總結

目前我自己遇到的找不到元素大致是這些情況,希望能幫助大家跳坑。

 

~~~下課鈴~~~

 

【往期熱門文章】:

【Python成長之路】10行代碼教你免費觀看無廣告版的《慶餘年》騰訊視頻

【Python成長之路】如何用python開發自己的iphone應用程序,並添加至siri指令

【Python成長之路】從 零做網站開發 -- 基於Flask和JQuery,實現表格管理平臺

點擊下方詩句,可以留言互動喔  

                 我見衆生皆草木,唯你是青山

 

【關注“鵬哥賊優秀”公衆號,回覆“python學習材料”,將會有python基礎學習、機器學習、數據挖掘、高級編程教程等100G視頻資料,及100+份python相關電子書免費贈送!】

 

掃描二維碼

    與鵬哥一起

學python吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章