【祿】道高一尺 魔高一丈 Bloomberg 最新股價擷取法

話說最近 Bloomberg 更改了報價頁面,頁面上最新報價的 Class Name 更新增了亂碼!如果讀者嘗試利用早前筆者介紹的方法建立智能秘書,恐怕這回會給 Bloomberg 打敗。但對於有少許程序編寫底子的筆者而言,這次 Bloomberg 的改動也許有點侮辱了筆者以及各編程員的智慧



筆者的股票監察表建立於 Google Sheets 而股價資料主要來自 GoogleFinance 和 Bloomberg。月初旅行前後開始,筆者發現從 Bloomberg 很多時候都取不到股價。由於 Bloomberg 的股價是利用 XPath 在第三方網站取得的,並不如 GoogleFinance 函數在 Google Sheets 是原始支援,所以起初覺得偶有未能取價的情形也不足為奇。

及後遊日回來,筆者發現取股價的函數沒有一次成功(所以經常顯示筆者今個月股票倉賠了好幾萬元)。於是筆者沒有辦法,只好造訪 Bloomberg 網站看看究竟。

蒲開網站,很明顯的見到版面改動過來。未看原始碼,筆者心中已知道背後的原始碼肯定經過改動,目的就是防止我們這些「網路蛀米蟲」取股價又不看其網頁廣告;看來一些 XPath 工程少不免。資訊提供者往往借改版面更新視聽為名,打壓我們這班在免費資源的窄鏠之中生存的投資人為實。

再利用前文介紹過的方法,Highlight 股價 Inspect Element,筆者發現這回股價的 Class Name 新增了些幾個數字的亂碼

<span class="priceText__1853e8a5">1.16</span>

很明顯這次網頁的改動就是防止一般大眾編程員隨便的擷取股價!在這裡請讓筆者解釋一下。

在以前的 Bloomberg 頁面,股價的原始碼一行是這樣的:

<div class="price">1.16</div>

只要看穿了這個原始碼結構,然後利用 XPath 告訴 Google Sheets 擷取所有在 DIV 標籤內 Class 屬性值為「Price」的內容,就可以輕易取得股價:

=importxml("https://www.bloomberg.com/quote/RW0U:SP","//div[@class='price']")

就算讀者不懂得將上面的一段文字化為 XPath,大概也能理解文字的內容吧!筆者知道坊間其實有些網路小程序,使用家可以在完全不懂編程的情況下擷取網頁資訊(例如股價),其方法就是閱讀用家希望擷取的資訊附近的特徵(DIV 內 Class 屬性為 Price),然後替用家完成編程的部分。所以在從前 Bloomberg 頁面,要取得股價基本上是幼稚園生也能做到的。

好了,現在 Bloomberg 在股價(以及其他資訊)的 Class 值安插了一堆亂碼,以上的方法就不奏效了。為什麼?因為就算讀者根據上面的 screen capture 寫了一下一段 XPath:

=importxml("https://www.bloomberg.com/quote/RW0U:SP","//span[@class='priceText__1853e8a5']")

Google Sheets 在執行 ImportXML 函數時,會重新載入 Bloomberg 頁面,而 Bloomberg 伺服器會在 Class 值重新產生出新的亂碼。結果,ImportXML 函數沒能在新的頁面找到舊的亂碼,回傳結果 #N/A!。利用上述網路小程序擷取股價的話,當然也只有投降了。

但若讀者有少許編程基礎和數據科學的感知,應該不難在新的網頁原始碼找到新的特徵。事實上,筆者認為 Bloomberg 侮辱各位讀者智慧的地方,在於其在新頁面中股價的 Class 值仍然大大隻字寫著 priceText。只要有方法利用 XPath 表達式寫出 Class 值「內含有」(而非「等於」)「priceText」,單憑這點已經完全夠打。

網路資源豐富的今天,要找出如何寫這句其實只需要 30 秒。而答案是:

=importxml("https://www.bloomberg.com/quote/RW0U:SP","//span[contains(@class,'priceText')]")

未知道 Bloomberg 的網路編程員,花了多少時間和資源去修改這個頁面?然後 1 分鐘內就被筆者破解,這故事聽起來有沒有些大衛打到巨人哥利亞的味道?

4 則留言:

  1. 未知道 Bloomberg 的網路編程員,花了多少時間和資源去修改這個頁面?然後 1 分鐘內就被筆者破解,這故事聽起來有沒有些大衛打到巨人哥利亞的味道?
    完全沒有,因為這個大衛智力及收入都比哥利亞高!HAHAHAHAHA

    回覆刪除
    回覆
    1. 哈哈,以 Bloomberg 整個編程團隊,筆者不可能以智慧和收入超越吧 :)

      刪除
  2. 用亂碼class來阻擋資料擷取?如果真是這樣,這個Bloomberg的程式員沒用過Regular expression吧...這不可能吧,真奇怪...
    要對應阻止資料擷取在有經驗的程序員身上只是時間投放的問題。

    回覆刪除
    回覆
    1. 所以我認為這次 Bloomberg 的做法不是要趕盡殺絕,只是想用最低的成本解決最低層次的 Parsing。即用 1% 資源搞掉也許 40%-50% 的 Traffic。

      刪除

熱門文章