加密貨幣錢包地址資產監視器 - 用 Python 的 XPath 擷取 html 結構資料

用 python 爬蟲抓取加密貨幣瀏覽器上的資料

 

上一篇加密貨幣冷錢包監視器 - Python 爬蟲教學中,流浪貓是以 Python 的 selenium 模組與 chromedriver 工具,搭配 driver.find_element 找尋特定的 CLASS_NAME 來取得加密貨幣資產數據。

 

 

然而麻煩的是,有些網站的 CLASS_NAME 會重複使用,甚至讓 div 和 span 資料互相交錯,造成爬蟲在抓資料時出現錯誤。以下我將以漫談的方式,介紹如何使用 XPath 擷取乙太幣區塊鏈瀏覽器 etherscan 的資料。翠維尼

 

 

找出目標欄位的 XPath 位置

於網頁中的乙太幣數量資料按右鍵 > 檢查 啟動開發者工具 (DevTools) 後,在右方欄位的 html 結構中找尋目標的標籤位置,按右鍵 > copy > copy full XPath 。


抓到的路徑看起來會像這樣:

/html/body/div[1]/main/div[4]/div[2]/div[1]/div[2]

 

 

用 Python 的 XPath 抓取 html 結構節點

建議可以直接將位置設為變數,未來要修改比較方便。而在擷取到資料後,可以用 re.sub 來清理無用的字元和符號,記得要在 re.sub 內部加上 r' ' 或者用兩條 \\,才能讓 Python 忽略程式碼中的反斜線(\),否則 \ 會被解譯為跳脫字元,自然也無法獲得想要的結果。

 

程式碼示範:


eth_COIN = "/html/body/div[1]/main/div[4]"

eth_Token_COIN = driver.find_element(By.XPATH, eth_COIN).text
eth_Token_COIN_1 = re.sub(r'[\n\t\s]|[a-zA-Z]', '', eth_Token_COIN)

 

 

用正規表達式抓取特定符號之間的字串或數值

由於我們的目標是將資料整理成『加密貨幣數量』與『美金總價』,但在美金價格的欄位中,網站卻把 div 和 span 的資料寫在一起,造成無法用一般的方法直接取得數值。對於這個問題,我們可以用更進階的正規表達式來處理。

 

Python 抓到的原始字串:

$88.88 (@ $1,567.36/ETH)

 

我們的目標是『錢包中的乙太幣美金價』,因此可以用正規表達式取出 $ 和 ( 符號中間的數值,最後用 re.findall 將它列出來。如果不希望印出的數值被 [ ] 符號夾住,可以在結尾的部份給予 [0],讓它印出第一個答案。

 

pri = r'(?<=\$)(.*?)(?=\()' 
s = eth_Token_USD_1

print(re.findall(pri, s)[0], ')

 

88.88

 

 

最終程式碼

整合以上的關鍵步驟後,就能打造出專門獲取 etherscan 和 polygonscan 網站上乙太幣與 Polygon 鏈上 Matic 資產的爬蟲了。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import re
import time

s = Service("/home/PycharmProjects/chromedriver/chromedriver")
driver = webdriver.Chrome(service=s)

print("\n" + time.strftime('%Y-%m-%d, %H:%M:%S'), file=open('eth.csv', 'a'), end=', ')

eth_coin = ['https://etherscan.io/address/0x3...',
            'https://polygonscan.com/address/0x3...',
            ]

for i in eth_coin:
    driver.get(i)
    time.sleep(5)
    eth_COIN = "//*[@id='ContentPlaceHolder1_divSummary']/div[1]/div[1]/div/div[2]/div[1]/div[2]"
    eth_USD = "//*[@id='ContentPlaceHolder1_divSummary']/div[1]/div[1]/div/div[2]/div[2]/div[2]"

    eth_Token_COIN = driver.find_element(By.XPATH, eth_COIN).text
    eth_Token_COIN_1 = re.sub(r'[\n\t\s]|[a-zA-Z]', '', eth_Token_COIN)

    eth_Token_USD = driver.find_element(By.XPATH, eth_USD).text
    eth_Token_USD_1 = re.sub(r'[\n\t\s]|[a-zA-Z]|', '', eth_Token_USD)
    pat = r'(?<=\$)(.*?)(?=\()' 
    s = eth_Token_USD_1

file=open('coin/eth-poly.csv', 'a'))
    print(eth_Token_COIN_1, ", ", re.findall(pat, s)[0], ', ', end='', file=open('coin/eth-poly.csv', 'a'))

driver.close()

 

用試算表 Calc 整理資料

在爬蟲將網頁資料梳理成 csv 檔之後,我們會希望將這些原始資料整理成表格或圖表,提昇可讀性。

 

雖然可以用 Calc 和 Excel 的連結至外部資料功能,將外部的 calc 抓到統合的試算表 (ods) 中進一步整理,但本文 Python 程式碼所產生的資料列是「由上至下、由舊到新」依序新增的,如果直接拿來用的話,試算表通常只能抓到最舊的資料列,或用手動的方式更改欄位,因此使用起來相當不方便。那麼該如何用函數抓出欄位最後一列 (最新) 的數值呢?

 

對於這個問題,其實我們可以用 Excel 和 Calc 都通用的 LOOKUP 函數來解決,示範如下:

 

=LOOKUP(2,1/ISNUMBER(A1:A65548),A1:A65548)

 

只要將 A 欄位改成你想要的欄位,即可抓取欄位中最新一列的數值。

 

 

 

延伸閱讀

加密貨幣冷錢包監視器 - Python 爬蟲

regexstorm 測試正規表達式

Python 3.8: re 模組

我的 python 筆記與練習範例

更多加密貨幣

 

 

 

留言

這個網誌中的熱門文章