iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
AI & Data

網路爬蟲,萬物皆爬 - 30 天搞懂並實戰網路爬蟲及應對反爬蟲技術系列 第 19

【Day 19】- 讓 Selenium 去 Dcard 上爬文! (實戰 Selenium 模擬使用者划手機 1/2)

  • 分享至 

  • xImage
  •  

前情提要

前一篇與大家介紹了 Selenium 的基本運用,並在補充資料中給予了語法的資源。

開始之前

今天要帶各位寫一隻能夠爬取 Dcard 上文章的爬蟲,是透過 Selenium 去撰寫。

預期效果

透過 Selenium 成功開啟 Dcard 分頁(瀏覽器分頁)

用 Selenium 內建的鎖定工具爬取目前的所有文章

將文章存於 JSON 檔案中

實作

首先,先簡單撰寫一個 Selenium ,讓 Selenium 去開 Dcard 網站 https://www.dcard.tw/f

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')

接下來用開發工具觀察一下文章元素是否有 class 讓我們爬取。發現有 tgn9uw-0 bReysV 這個 class。

我們可以用 driver.find_elements_by_class_name 來定位該元素們,並用個 for-loop 將回傳的 list 遍歷過一遍後輸出。

如果沒有鎖定到,有可能是還沒有載入完成就爬取造成的,這時候我們能用 time 庫裡面的 sleep 來讓整個程式暫停 0.5 秒讓資源載入完成。

from selenium import webdriver
from time import sleep
if __name__ == '__main__':

    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')

    sleep(2)
    eles = driver.find_elements_by_class_name('tgn9uw-0')
    for ele in eles:
        print(ele)
    driver.quit()

'''
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="ee2da9f1-a5d0-41fc-80d7-63bf394e7267")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="02573927-21b1-405c-9310-8a050aa6ec8f")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="584200b4-5633-44f4-a048-e2bd3ebeb636")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="aa05e5c6-defb-4087-84b3-a9d6dbe4131d")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="85badbb3-7238-4b6e-9892-b7e71e8ac2f9")>
'''

將標題、連結、副標鎖定後存到變數中。

from selenium import webdriver
from time import sleep
if __name__ == '__main__':
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    sleep(2)
    eles = driver.find_elements_by_class_name('tgn9uw-0')
    for ele in eles:
        title = ele.find_element_by_class_name('tgn9uw-3').text
        href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
        subtitle = ele.find_element_by_class_name('tgn9uw-4').text
        print(title)
        print(href)
        print(subtitle)
    driver.quit()

將結果存於一個 dist 中,並 append 到總結果當中。

from selenium import webdriver
from time import sleep
if __name__ == '__main__':
    results = []
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    sleep(2)
    eles = driver.find_elements_by_class_name('tgn9uw-0')
    for ele in eles:
        result = {}
        title = ele.find_element_by_class_name('tgn9uw-3').text
        href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
        subtitle = ele.find_element_by_class_name('tgn9uw-4').text
        result = {
            'title': title,
            'href': href,
            'subtitle': subtitle
        }
        results.append(result)
    print(results)
    driver.quit()

接下來將結果存於 JSON 檔案中。

from selenium import webdriver
from time import sleep
import json

if __name__ == '__main__':
    results = []
    driver = webdriver.Chrome()
    driver.get('https://www.dcard.tw/f')
    sleep(2)
    eles = driver.find_elements_by_class_name('tgn9uw-0')
    for ele in eles:
        result = {}
        title = ele.find_element_by_class_name('tgn9uw-3').text
        href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
        subtitle = ele.find_element_by_class_name('tgn9uw-4').text
        result = {
            'title': title,
            'href': href,
            'subtitle': subtitle
        }
        results.append(result)
    print(results)
    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()

結語

今天分析了文章的元素特徵,用了 Selenium 模擬使用者鎖定所有文章的元素,之後操作鎖定到的元素將其存在變數中,整理到一個字典,並塞入一個串列中,最後將串列存到 JSON 檔案中。

明日內容

明天將用 Selenium 模擬使用者滾動頁面(划手機 or 滾輪),並將文章爬取下來。

補充資料

Dcard : https://www.dcard.tw/f

Selenium with Python docs : https://selenium-python.readthedocs.io/

Selenium docs : https://readthedocs.org/projects/selenium-python/downloads/pdf/latest/


上一篇
【Day 18】- 像個使用者的爬蟲 Selenium
下一篇
【Day 20】- 讓 Selenium 去 Dcard 上自動向下捲動 (實戰 Selenium 模擬使用者划手機 2/2)
系列文
網路爬蟲,萬物皆爬 - 30 天搞懂並實戰網路爬蟲及應對反爬蟲技術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
lrq20501
iT邦新手 5 級 ‧ 2023-02-03 15:11:32

學習中…但目前的網頁的 article class的元素似乎找不太到…一整串很長!可以解答一下嗎,謝謝。:)

Vincent55 iT邦新手 4 級 ‧ 2023-02-14 18:04:18 檢舉

我剛稍微看了一下還有,看要不要使用隨機等待[1]的方式讓資料渲染完,或者直接使用比較推薦的 Dcard API [2]抓資料。

[1] __import__("time").sleep(__import__("random").randint(2, 5))
[2]https://www.dcard.tw/service/api/v2/posts

我要留言

立即登入留言