1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        我用 Selenium 爬了京東商城,結(jié)果……

        共 4579字,需瀏覽 10分鐘

         ·

        2021-09-04 17:06

        文 | 極光

        來源:Python 技術(shù)「ID: pythonall」



        今天跟大家一起學(xué)習(xí)下 Python 如何使用 Selenium 進(jìn)行自動化操作網(wǎng)頁。

        如何加載元素

        眾所周知現(xiàn)在的網(wǎng)站,頁面內(nèi)容非常復(fù)雜,而且加載的內(nèi)容種類繁多,所以加載時間就會比較長。平時我們看到的大部分網(wǎng)站頁面都做了優(yōu)化,比如 baidu.com,或者 jd.com,但為了提升頁面打開速度,他們又都采用了不同的方案:

        • 百度首頁采用了極簡的方式,讓自己搜索首頁盡量加載少量的內(nèi)容,以提高打開頁面的速度。

        • 京東首頁則不可能采用百度那樣的方案,因?yàn)闃I(yè)務(wù)方向不同,京東作為電商需要給客戶展示盡量多的內(nèi)容,所以它采用了延時加載的方式,也就是先加載用戶能看到的內(nèi)容,然后再慢慢加載那些用戶不能直觀看到的內(nèi)容,從而大大提高了頁面打開的速度。

        上次我們用 selenium 寫了個爬取京東商城搜索出來的 ps5國行 的產(chǎn)品名稱和價格,在這里把代碼再放出來看下。

        # 導(dǎo)入庫
        from selenium import webdriver
        import time

        # executable_path 用于指定driver存放路徑
        browser = webdriver.Chrome(executable_path='/Users/xx/python/chromedriver')
        # 打開京東官網(wǎng)
        browser.get('https://www.jd.com/')

        # browser.find_element_by_id("kw").send_keys("python selenium")

        # 獲取輸入框?qū)ο?/span>
        search = browser.find_element_by_xpath('//*[@id="key"]')

        # 輸入想要搜索的關(guān)鍵詞,如"ps5國行"
        search.send_keys('ps5國行')

        # 獲取搜索按鈕對象并單擊
        browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()

        # 將滾動條移動到頁面底部,用于加載所有信息
        javascript = "var q=document.documentElement.scrollTop=50000"
        # 執(zhí)行 javascript 移動滾動條
        browser.execute_script(javascript)
        # 等待3秒,有些異步加載的數(shù)據(jù)加載慢
        time.sleep(3)

        # 通過查看頁面源碼得到金額的 xpath 路徑,并獲取金額 
        prices = browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li/div/div[2]/strong/i')
        # 通過查看頁面源碼得到商品標(biāo)題的 xpath 路徑,并獲取商品標(biāo)題
        names = browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li/div/div[3]/a/em')

        # 遍歷打印出當(dāng)前頁所有標(biāo)題和金額
        for name,price in zip(names,prices):
            print(name.text.replace('\n',''),price.text)

        #退出瀏覽器
        browser.quit()

        元素等待

        上面代碼中,在搜索完成后,我們只看到第一頁內(nèi)容,其實(shí)還沒在屏幕上展示的內(nèi)容是沒有加載的,這樣我們就沒辦法獲取所有搜索出的產(chǎn)品信息。

        這里就需要我先用 selenium 操作滾動條,將滾動條移動到頁面底部,用于加載所有信息,這時你會發(fā)現(xiàn),產(chǎn)品信息不會立刻加載出來,還需要等待幾秒鐘,當(dāng)然等多久主要還是看網(wǎng)速。

        在這里我設(shè)置的是等待 3 秒,調(diào)用了 time.sleep(3) 方法來實(shí)現(xiàn)。

        • 強(qiáng)制等待

        強(qiáng)制等待是一種簡單又粗暴的方式,也就是強(qiáng)制將進(jìn)程暫停,等待參數(shù)傳入的相應(yīng)時間。比如我們上面用的 time.sleep(3),它不會管你頁面是否已經(jīng)加載完,都會等 3 秒的時間。

        如果 3 秒后內(nèi)容加載完了還好,如果沒有加載完,它也不會再等了,直接開始執(zhí)行下面的代碼,所以經(jīng)常會遇到不可預(yù)知的問題。

        這種方式主要用來簡單調(diào)試代碼時使用,平時非常不建議使用。

        • 隱式等待

        隱式等待也叫隱性等待,跟強(qiáng)制等待最大的不同就是,隱性等待可以實(shí)現(xiàn)智能等待,只要設(shè)置一個最大等待時間,在這個時間內(nèi)網(wǎng)頁內(nèi)容只要加載完成就可以立即進(jìn)行后續(xù)操作,不需要再等到最大時間。

        # 導(dǎo)入庫
        from selenium import webdriver
        import time

        # executable_path 用于指定driver存放路徑
        browser = webdriver.Chrome(executable_path='/Users/xx/python/chromedriver')

        # 隱性等待最長等20秒
        driver.implicitly_wait(20)  

        # 打開京東官網(wǎng)
        browser.get('https://www.jd.com/')


        #退出瀏覽器
        browser.quit()

        不過使用隱性等待有幾點(diǎn)需要注意:

        1. 如果等待到最大時間,網(wǎng)頁還沒有加載完成,那依然還會繼續(xù)執(zhí)行下一步操作。

        2. 這里指的網(wǎng)頁加載完成,是指瀏覽器的加載頁面狀態(tài)顯示完成(也就是加載的小圈不再轉(zhuǎn)),實(shí)際使用中經(jīng)常會遇到大部分內(nèi)容都加載完了,但有少量 js 腳本一直加載中,導(dǎo)致整個頁面狀態(tài)還是加載中,這時就會仍需要等待 20 秒才會執(zhí)行下一步操作。

        3. sleep() 方法不同,隱式等待方法 implicitly_wait(20) 設(shè)置一次后是全局有效的,也就是在整個 driver 的周期都起作用,不用每個操作前都設(shè)置一遍。

        那這些問題有沒有解決方法?或者有沒有其他更好的方法實(shí)現(xiàn)元素等待?當(dāng)然有,那就是顯式等待。

        • 顯式等待

        顯式等待其實(shí)就是 wait 模塊下的 WebDriverWait 類對象,通過 until() 方法和 until_not() 方法實(shí)現(xiàn)元素等待。

        until():當(dāng)某個元素加載完成,或者其他設(shè)置的條件成立,則會繼續(xù)執(zhí)行后續(xù)操作。如果還不滿足條件,則會間隔一定時間檢測一下條件是否成立,直到達(dá)到設(shè)置的最大時間,最后拋出異常 TimeoutException。

        until_not():跟 until()  方法相反,當(dāng)判斷某個元素,或者某個條件不成立時,才會繼續(xù)執(zhí)行下一步操作。

        # 方法參數(shù)說明
        WebDriverWait(driver, 超時時間, 頻率, 忽略異常).until(可執(zhí)行的方法, 超時會返回信息內(nèi)容)

        下面我們來看這段代碼

        # 導(dǎo)入庫
        from selenium import webdriver
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as ECS
        from selenium.webdriver.common.by import By
        import time

        # executable_path 用于指定driver存放路徑
        browser = webdriver.Chrome(executable_path='/Users/xx/python/chromedriver')

        # 打開京東官網(wǎng)
        browser.get('https://www.jd.com/')

        # 定位要查找的元素
        loc = (By.LINK_TEXT, "打開")

        try:
          # 等待5秒,直到發(fā)現(xiàn)元素
            WebDriverWait(driver, 5).until(ECS.presence_of_element_located(loc))
        except:
          # 沒有發(fā)現(xiàn)元素則會打印提示
            print("沒有找到對應(yīng)元素!")
        finally:
          # 發(fā)現(xiàn)元素則執(zhí)行下面的方法
            driver.find_element_by_link_text('打開').click()

        #退出瀏覽器
        browser.quit()

        使用 WebDriverWait 調(diào)用可執(zhí)行方法,除了可定位的元素,還可以使用 selenium 提供的 expected_conditions 模塊中的各種條件,也可以使用 WebElementis_enabled(),is_selected()is_displayed() 等等方法。

        總結(jié)

        好了,今天我們又介紹了下 selenium 元素加載時的三種等待方法,以及等待方法的優(yōu)缺點(diǎn),在使用場景下該如何操作等。并寫了一些簡單例子,給大家學(xué)習(xí)參考,后續(xù)還會為大家介紹更多。OK,今天就聊這些,如果你喜歡記得點(diǎn) 在看

        ············END············


        上期送書中獎名單來咯,速來圍觀~


         書籍名單



        恭喜以上六位中獎的童鞋,快加小編微信(Mayyy530),憑中獎截圖來領(lǐng)獎!先到先選哦~


        兌獎截止時間:9月3日16:00整



        往期推薦

        1、10 個“瘋狂”的 Python 項(xiàng)目創(chuàng)意(文末送書)

        2、視頻剪輯什么鬼?Python 帶你高效創(chuàng)作短視頻

        3B 站 CEO 的身份證被上傳到 GitHub 了?

        4、找不到阿里云盤資源?趕緊收藏這個福利網(wǎng)站!

        5、Edge瀏覽器大翻車:頁面出現(xiàn)無法關(guān)閉的“中國特供版”廣告,網(wǎng)友炸了

        今天因?yàn)槟狞c(diǎn)贊和在看,讓我元?dú)鉂M滿!

        瀏覽 85
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日韩免费在线观看视频 | 俺也来俺也去俺也色 | 亚洲无码一二三区 | 国产福利99 | 给少妇添下面喝尿 | chinese野外求欢bbw 久久免费偷拍 | 成人无码区免费AⅤ片在线观看 | 精品国产aⅴ麻豆 | 91精品一区| 欧美日韩日逼视频 |