iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

養爬蟲的人學爬蟲系列 第 21

【Day 21】在Dcard上自動向下捲動吧!(實戰Selenium 1/2)

  • 分享至 

  • xImage
  •  

閒聊
昨天我們使用Selenium爬了Dcard,今天要來使用模擬使用者的情況來繼續爬Dcard 。

預期

  1. 使用者可以捲動頁面(捲動次數和文章數)。
  2. 爬取目前的文章,並且可以將畫面捲到最底下。
  3. 重複以上內容。

實作

  • 第一步我們會需要讓使用者,可以輸入捲動次數的程式。
from selenium import webdriver
from time import sleep
import json

if _name_ = '_main_' :
    scroll_time = int(input('請輸入捲動次數'))
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
  • 第二步要達成捲動的功能,可以在Selenium中支援JavaScript的功能。
    這裡可以用到JavaScript的 window.scrollTo來達到我們想要的效果。
from selenium import webdriver
from time import sleep
import json

if _name_ = '_main_' :
    scroll_time = int(input('請輸入捲動次數'))
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    sleep(2)
    js = window.scrollTo(0, document.body.scrollHeight)
    driver.execute_script(js)
  • 第三步就是寫一個for-loop來讓程式重複執行,同時如果遇到元素問題(文章刪除或是廣告...等),可以在迴圈中加入 try-except讓程式順利運行。
from selenium import webdriver
from time import sleep
import json

if _name_ = '_main_' :
    scroll_time = int(input('請輸入捲動次數'))
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    result = []
    for now_time in range(1, scroll_time+1) :
        sleep(2)
        eles = driver.find_element_by_calss_name('sc-afbc95aa-0')
        for ele in eles :
            try :
                title = ele.find_element_by_class_name('sc-afbc95aa-2').text
                href = ele.find_element_by_class_name('sc-afbc95aa-2').get_attribute('href')
                subtitle = ele.find_element_by_class_name('sc-5914a055-0').text
                result = {
                     'title' : title 
                     'href' : href 
                     'subtitle' : subtitle 
                }
                results.append(result)
            expect :
                pass
        print(f"now scroll {now_time}/{scroll_time}")
        js = window.scrollTo(0, document.body.scrollHeight)
        driver.execute_script(js)
    with open('Dcard-articles.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, indent=2,
                  sort_keys=True, ensure_ascii=False)
    driver.quit() #關閉瀏覽器
  • 完整程式碼
    如果碰到文章有重複爬取,可以在下次爬取時將那個重複的元素刪除就好,或是可以只爬取重複元素後面的元素。
from selenium import webdriver
from time import sleep
import json

if _name_ = '_main_' :
    scroll_time = int(input('請輸入捲動次數'))
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    result = []
    prev_ele = None
    for now_time in range(1, scroll_time+1) :
        sleep(2)
        eles = driver.find_element_by_calss_name('sc-afbc95aa-0')
        try :
            eles = eles[eles.index(peve_ele):]
        except :
            pass
        for ele in eles :
            try :
                title = ele.find_element_by_class_name('sc-afbc95aa-2').text
                href = ele.find_element_by_class_name('sc-afbc95aa-2').get_attribute('href')
                subtitle = ele.find_element_by_class_name('sc-5914a055-0').text
                result = {
                     'title' : title 
                     'href' : href 
                     'subtitle' : subtitle 
                }
                results.append(result)
            expect :
                pass
        prev_ele = eles[-1]
        print(f"now scroll {now_time}/{scroll_time}")
        js = window.scrollTo(0, document.body.scrollHeight)
        driver.execute_script(js)
    with open('Dcard-articles.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, indent=2,
                  sort_keys=True, ensure_ascii=False)
    driver.quit() #關閉瀏覽器

結語
今天練習了捲動的技巧,也順利的讓程式碼執行了!
明天一起來聊聊網頁自動化這件事情~

明天!
【Day 22】認識並實作哈希值

參考資料
HTML DOM 快速導覽 - window 物件的方法 scrollTo()https://pydoing.blogspot.com/2011/10/javascript-window-scrollto.html
原生js window.scrollTo平滑滾動到頁面的某個位置https://www.796t.com/content/1541737292.html


上一篇
【Day 20】帶上工具去Dcard去爬文(實戰Selenium 1/2)
下一篇
【Day 22】認識並實作哈希值(hashlib模組)
系列文
養爬蟲的人學爬蟲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言