Python 爬蟲教學-我們來做一個IG抽獎神器吧!(中)

前言

上回我們讓我們的瀏覽器能夠成功完成了登入的步驟,而這只是第一步而已,今天會教大家這次教學的重頭戲,也就是如何在需要進行不斷滑動的網頁(動態網頁)做爬蟲,如果還沒看過上一篇的朋友,連結在這邊

Python -程式碼講解

在開始講解之前,我們一樣要先理清楚我們接下來要執行的步驟,才能夠更好的在chromedriver上面執行我們的爬蟲,所以我們可以嘗試著用正常的網頁操作一遍看看需要什麼步驟

來到貼文頁面之後-> 將留言往下滑 -> 不斷地往下滑 -> 滑到底之後停止

這裡帶出了這個應用最難的一件事,如何讓留言不斷地往下滑?以及我怎麼判斷我的貼文已經到底了呢?首先讓我們先來解決第一個問題。

將留言往下滑

首先我們要理解,這種操縱網頁行為的動作呢,我們是無法透過Python內的代碼進行實現的,因為網頁的本質上還是使用JavaScript去做實現的,所以我們在這裡呢,就需要使用JavaScript的方法來做實現,我們來看下面這段程式碼。

browser.get(post_URL) #到達貼文網址,這邊不多說
post =  WebDriverWait(browser, 20, 0.5).until(EC.presence_of_element_located((By.XPATH,'//*[@id="react-root"]/section/main/div/div[1]/article/div[3]/div[1]/ul')))

scrollTop = browser.execute_script('arguments[0].scrollTop +=300;return arguments[0].scrollTop', post)

執行JavaScript的方法使用execute_script(),而指令要用我們必須要在其中加入arguments[0],也就是引數,這個引數會對應你放在後面的變數,所以就會長成以下這樣

browser.execute_script(‘引數+要執行的指令’,變數)

而這邊我們要執行的指令是scrollTop,這個代表元素和網頁最頂端的距離,所以我們可以透過JavaScript去操作這個元素,這樣就可以讓其執行不斷下滑的動作了,而問題來了,我們要怎麼知道哪一個元素才是要下滑的呢?

在某些網站,有些下滑區域旁邊都會有滾動條,而我們通常可以在這個元素中去找到scroll的屬性,而如果沒有明顯的滾動條像是IG那樣該怎麼辦呢?

我們一樣透過檢查這個動作叫出網頁的元素,並且隨便對著某個元素,再次點擊檢查,這樣就會進入一個狀態是,只要你點擊右邊的元素,左邊就會跟著出現對應的區域,就像上圖。

我們將其滑動到對應下滑的區域,找到了div.EtaWk這個屬性,這個時候我們必須要做第二個確認,也就是他的style裡面有沒有scroll這個屬性,因為對應下滑的區域不只有div.EtaWk,還有其下面的ul.XQXQT,我們必須要知道scroll是被編寫在哪一個屬性裡面,於是我們透過下方的style查找。

最後找到了ul裡面才有scroll的屬性,於是就有了我們上方post變數的由來,用這樣的方式就可以讓你的網頁做下滑的動作了。

不斷地往下滑

stop = False
while not stop:
        #滑動
        scrollTop = browser.execute_script('arguments[0].scrollTop +=300;return arguments[0].scrollTop', post)
        scroll_time+=1
        print(scrollTop)#測試
        if scrollTop>950: #每次scroll如果看得到load more就點 
            print("執行中")
            more_ele =  WebDriverWait(browser, 20, 0.5).until(EC.presence_of_element_located((By.XPATH,'//*[@id="react-root"]/section/main/div/div[1]/article/div[3]/div[1]/ul/li/div/button')))
            more_ele.click()
       time.sleep(1) #每次滑動都先停一秒,以方便觀測網頁狀況

首先我們先設置一個stop的條件,而只要還沒有達到stop的條件我們就持續執行程式碼,之後再來考慮要怎麼讓stop變成True,而我們再次手動去執行爬蟲的步驟,以了解接下來需要幹嘛,可以發現當你在IG不斷下滑之後,會出現一個+號的按鈕,需要點擊才會再次載入更多元素。

於是我們就設定當滑到一個程度時(950),而這個程度我們就必須要透過JS執行return scrollTop的指令才能在Python裡面使用,至於950是我個人測試的,大家可以根據自己的狀況去做微調,而按鈕的點擊就跟之前是一樣的道理,所以透過while + 下滑 + 遇到載入更多按鈕就按,我們就可以完成不斷地往下滑這個功能了。

滑到底之後停止

#終止條件
#迴圈中
if scrollTop>maxTop: #代表有下滑到則將maxtop換為新的
   maxTop = scrollTop 
elif scrollTop == maxTop: #代表上次的和這次的一樣
   stop = True

我們透過上一段中,不斷地print(scrollTop)會發現,scrollTop到底之後,就會停止增加了,如下面這樣

所以我們設置一個maxTop變數,只要每次有下滑都將maxTop設置為新的scrollTop,而若是新的scrollTop和maxTop一樣的話,就代表實際網站已經沒有辦法再下滑了,所以我們就可以將迴圈停止了,這就是如何判斷滑到底之後停止的辦法,以下是完整的程式碼。

browser.get(post_URL)

post =  WebDriverWait(browser, 20, 0.5).until(EC.presence_of_element_located((By.XPATH,'//*[@id="react-root"]/section/main/div/div[1]/article/div[3]/div[1]/ul')))
print(post)
scroll_time = 0

maxTop = 0 
stop = False
while not stop:
    #滑動
    scrollTop = browser.execute_script('arguments[0].scrollTop +=300;return arguments[0].scrollTop', post)
    scroll_time+=1
    print(scrollTop)
    if scrollTop>950: #每次scroll如果看得到load more就點 
        print("執行中")
        more_ele =  WebDriverWait(browser, 20, 0.5).until(EC.presence_of_element_located((By.XPATH,'//*[@id="react-root"]/section/main/div/div[1]/article/div[3]/div[1]/ul/li/div/button')))
        more_ele.click()
    #終止條件
    if scrollTop>maxTop: #代表有下滑到則將maxtop換為新的
        maxTop = scrollTop 
    elif scrollTop == maxTop: #代表上次的和這次的一樣
        stop = True
    time.sleep(0.3)

到這邊我們就已經將所有留言讀取完畢了,接下來就可以開始做資料的處理並且進行抽獎了!

那今天我們就先教學到這邊,有任何問題都可以在下面進行留言喔!

馬上看Python爬蟲教學 -試著作自己的搶購機器吧!(上)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *