iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Software Development

selenium爬蟲應用至discord bot系列 第 27

[DAY27]Discord bot取得網頁消息 - 1

  • 分享至 

  • xImage
  •  

接下來的四天讓我們用前面學過的內容來做一個簡單的discord bot爬蟲,這裡用的方法也許有些並不是最佳解但可以做為一個練習來使用。

首先我們使用以下網站作為範例。
https://bluearchive.jp/news/newsJump

此處僅作為練習使用,若網頁有架構上的變化需要根據需求更改程式碼。


進到範例網站後可以觀察到所有通知文章是包在class為.catalogueBox<div>標籤裡並且用<li>標籤顯示不同文章的標題。而每個<li>標籤都帶有click的事件監聽器。

接著觀察通知網頁的DOM後可以發現,每則通知中都至少含一張圖片,並且內容主要是使用<hr> 作為分區,且內容整體是包在class為.content_cen<div>標籤裡,並用多個<p>標籤顯示多個段落。

假設現在想要取得一篇最新的文章,內容取至第二個<hr>標籤為止,並且將通知網頁的第一張圖片作為discord Embed訊息的圖片,而Embed的顏色取網頁中第一個非黑色和紅色的文字顏色。


接著可以使用selenium來做模擬人的點擊操作來獲取最新的文章。

首先在專案資料夾下建立以下檔案

├─ color_fetch.js #獲取文字顏色
├─ fetch.js #抓取網頁內容
├─ fetch.py #抓取網頁內容
└─ split.py #從網頁內容中分出粗體文字的部分

fetch.js

// 獲取content_cen元素
let content = document.querySelector(".content_cen");
// 獲取content_cen元素下的所有<p>元素
let paragraphs = content.querySelectorAll("p");
// 創建一個空數組,用於存儲符合條件的<p>元素
let result = [];
// 計數器,用於計算<hr>標籤的數量
let hrCount = 0;
// 遍歷所有<p>元素
for (let p of paragraphs) {
  // 如果<p>元素的上一個兄弟元素是<hr>,則計數器加1
  if (p.previousElementSibling && p.previousElementSibling.tagName === "HR") {
    hrCount++;
  }
  // 如果計數器大於等於2,則跳出循環
  if (hrCount >= 2) {
    break;
  }
  // 如果<p>元素包含<strong>標籤,則在其內容前後各加一個底線字符'_'
  let strongs = p.querySelectorAll("strong");
  for (let strong of strongs) {
    strong.innerHTML = "_" + strong.innerHTML + "_";
  }
  // 如果<p>元素包含<img>標籤,則將其內容改為圖像的網址(src)
  if (p.querySelector("img")) {
    p.textContent = p.querySelector("img").src;
  }
  // 將<p>元素添加到結果數組中
  result.push(p);
}
// 返回結果數組
return result;

以上程式碼主要功能是:

  1. 從網頁中選取 class 為 content_cen 的元素,並取得其中的所有 <p> 段落標籤

  2. 遍歷每個 <p> 段落:

    • 如果段落上方是 <hr> 標籤,則 hrCount 計數器 + 1
    • 如果hrCount 大於等於 2,表示已超過內文範圍,因此跳出迴圈
  3. 對每個在內文範圍內的 <p> 段落進行處理:

    • 如果有 <strong> 加底線標記
    • 如果有 <img>,取代段落文字為圖片網址
  4. 最後將處理過的 <p> 段落加入結果陣列傳回

簡單來說,這段程式碼是在網頁內容中,過濾出正文區塊中的段落,並對段落中的部分格式進行處理,例如加底線和替換圖片,最後傳回結果。


color_fetch.js

// 建立空陣列儲存結果
let result = [];

// 查詢所有內容中有設定 color 樣式的 span 和 strong 標籤
var colors = document.querySelectorAll(".content_cen span[style*='color'], .content_cen strong[style*='color']");

// 迭代每個找到的標籤
for (let color of colors) {

  // 取得標籤的 color 樣式值
  let colorCode = color.style.color;
  
  // 將 color 值推入結果陣列
  result.push(colorCode);

}

// 傳回結果陣列
return result;

這段 JavaScript 程式碼的用途是從網頁內容中抓取所有設定了文字顏色的元素,並傳回其 CSS color 屬性值。

以上是獲取想要的網頁內容以及內容的一些前置處理,方便之後將樣式還原回去(粗體字)。

剩下的三個py檔留至明天講解。


上一篇
[DAY26]Discord bot Embed訊息
下一篇
[DAY28]Discord bot取得網頁消息 - 2
系列文
selenium爬蟲應用至discord bot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言