沒穿方服

索引

顯示╱隱藏內文
顯示具有 user-script 標籤的文章。 顯示所有文章
顯示具有 user-script 標籤的文章。 顯示所有文章

問題描述

我要把臉書貼文貼到其他網站作為引用資料來源,連結必須是永久連結,且文字能顯示相關資訊(理想是顯示貼文的「標題」)而不是「Facebook」「影片」這樣的文字。

實際作業會發現連結格式很亂,有些情況甚至是「登入後」看不到標題(網頁 title),反而要登出才有。

成果

Greasyfork → Facebook 取得帶標題連結,原始碼也放在 GitHub

在頂端塞一個小元件,把文章的「時間戳記連結」拖曳進去,就會找出「帶標題的連結」,顯示在一個小對話框,可以複製 HTML。

研究

每篇貼文的連結 URL,大家都是由網頁上「時間戳記」的部分取得(臉書主要只曝露在這裡),然而根據貼文露出方式(在動態牆、彈出對話框、影片推廣等),同一篇貼文有多種不同連結,點進去看到的可能也不一樣。

連結就在「時間」上面

只能盡量列舉處理,想辦法轉換成「標題最完整」的連結構造。

也參考 Facebook 登入牆移除器(有提供「永久連結/標準網址」功能)已處理的各種格式,它還有從網頁 meta 甚至 JS relay(臉書的內部實作)偵測標準連結的實作(我沒有做)。

目前已知的格式

  • 使用者貼文 /{user}/posts/{id}

    例如 https://www.facebook.com/twreporter/posts/pfbid0bDDP6YCaEfULbAjBruvVbHVySX2iemoHCQRnaeKipNtbpDcx2Tz71WUqDnQZdWDTl?__cft__[0]={省略}&__tn__={省略}

    把追蹤參數移除即可,標準網址為: https://www.facebook.com/twreporter/posts/pfbid0bDDP6YCaEfULbAjBruvVbHVySX2iemoHCQRnaeKipNtbpDcx2Tz71WUqDnQZdWDTl

  • 群組內的貼文 /groups/{group}/posts/{id}

    例如 https://www.facebook.com/groups/Show.YMSNP/posts/1532962150583712/?__cft__[0]={省略}&__tn__={省略}

    也是移除追蹤參數即可。

  • 有永久連結參數 /groups/{group}/?multi_permalinks={id}

    例如 https://www.facebook.com/groups/667899516591545/?multi_permalinks=26147630041525142&notif_id={省略}&notif_t=feedback_reaction_generic&ref=notif

    移除追蹤參數,並統一轉為 posts/{postId} 格式: https://www.facebook.com/groups/667899516591545/posts/26147630041525142

  • 影片:Reel /reel/{id}

    例如 https://www.facebook.com/reel/1421756105769991/?__cft__[0]={省略}&__tn__={省略}

    移除追蹤參數,並統一轉為 video.php?v= 格式: https://www.facebook.com/video.php?v=1421756105769991

  • 影片:Watch /watch/?v={id}

    例如 https://www.facebook.com/watch/?v=1221241823458045

    移除追蹤參數,並統一轉為 video.php?v= 格式: https://www.facebook.com/video.php?v=1221241823458045

  • 影片:使用者貼文 /{user}/videos/{id}/

    例如 https://www.facebook.com/FANCA.Taiwan/videos/653740892754035/

    這個形式帶有 user 資訊,比前面只有 id 的品質好,所以移除參數即可,盡量保留原狀。

無能為力

  • 時間戳記的卵連結

    從「時間戳記」取得連結有一個限制,就是連結剛出現時,上面 URL 的值是隱蔽、編碼過的,這是臉書的設計,要等使用者互動時(例如滑鼠移到該連結上)才會動態變換為我們要的 URL。

    沒辦法,只好麻煩使用者手動滑一下。

  • 實在抓不到標題

    前面的研究,最後仍無法 100% 應付所有情境,有發現一些貼文出現在首頁動態牆時,看起來是有文字敘述的,但從那個連結就是只能連到降級的網頁,除非進入貼文作者的頁面找出原文,否則就是拿不到文字。

    不強求,只要最後拿到標題仍是「Facebook」這樣,就放棄,顯示警告就是了:

    🦴☠️ 只找到預設標題,可能需手動探索才能發現文字敘述(如果有的話)

又寫了一支臉書用的 user script → Facebook 乾淨連結
原始碼也放在 GitHub

連結污染

Facebook 對於外部連結,現在會用迂迴的方式竄改:網頁一開始顯示時,游標滑過連結還能在 tooltip 看到正常 URL,但點下去(不管左鍵、右鍵)或一些互動後,它會即時把連結變成 /l.facebook.com/l.php?u=原網址 這樣的轉址,讓你實際點到的是另一個 URL,這個感覺很噁心。

另外也會對連結附上 ?fbclid=... 這串很長的追蹤參數,要比較嚴謹地分享時,要刻意拿掉它也是很麻煩的。

既存替代方案

瀏覽器套件 ClearURLs 會移除所有網址中的追蹤碼。

差異在於我的 script:

  1. 就是只針對臉書。 utm_source 之類(Google 的追蹤碼)的不予理會
  2. 即時改網頁,而不是點擊連結後才用瀏覽器內部功能處理

立場

我不排斥追蹤,上網也從來不擋廣告。 單純是針對 Facebook。

點開報導者 The Reporter 的文章,有時會發現鍵盤 PageDown 不能滾動捲軸,毫無反應。

Chrome 的話 PageDown 可以用,但 Home End 還是壞的。

寫了一支 user script 自救,放在 Greasy Fork → 報導者優蛇 (twreporter-user) / 原始碼也有放在 GitHub

原理

起因是網站頂端搜尋列 (Search Bar) 輸入框有 autoFocus 設定,網頁技術用 React,輸入框錨上去後會搶走 focus,而瀏覽器行為會讓捲軸跟上,這是為什麼會捲到頂端。

又因為 focus 在輸入框,所以敲鍵盤也都被它吃掉,加上輸入框在畫面上還看不見,就變成鍵盤不理人的情形。

React 的 autoFocus 不同於標準 autofocus 屬性,DOM 裡面看不到,React 會自己模擬那個行為(你也不想每次 re-render 都 autofocus 吧)。

治本的方法是不要用 autoFocus,我有開一個 PR,但還未被處理。

補一下表態,報導者很多專題網頁都做超棒,也擁抱開源,契合組織理念,以開發者觀點我高度推崇。

可能在打 12 月商戰,搜尋商品被帶到 momo「店+」的頁面,又被手機版面傷到眼睛。
網址長得像這樣: www.momoshop.com.tw/TP/TP0003616/goodsDetail/TP00036160000057?entpCode=略

在桌面大螢幕看針對 App 做的版面,傷眼 點到行銷頁也會被 App 限定擋住

momo 不尊重桌面版(電腦版)使用者

很久以前點到手機版(.m 開頭)連結就死不做轉向或改善,經查 mo店+ 是今年三月上線的營運模式,APP 限定,現在年底了,網址散布開來了還是不改,你用桌面版點進來是你的問題,沒有要服務你。

更新 user script

更新之前寫的 MOMO 購物網「切換至桌面版」user script,現在會偵測店+ 網址,但無法導到桌面連結(因為不存在),點按鈕只會調整 <body> 寬度,讓版面正常一點點。

也幫按鈕增加一點表情。

一般按鈕 / 偵測到店+ 的按鈕 / 生氣膨脹的按鈕

Web 愛好者應該減少用 momo 買東西。

惱人的自動重整

在 Facebook 首頁(動態消息),如果離開分頁或閒置一段時間再回來,就有機會碰到自動重新整理,會把原本牆上的東西全部消掉。

動態消息會出現什麼內容是 Facebook 決定的,也沒有順序,所以一旦重刷就很難找回原本在看的文章,至少必須先看它推給你的垃圾。

參考 reddit 討論 How do I turn off auto-refresh on my feed when I click out of my Facebook tab? : r/facebook 有提到一個對策,就是裝 Always Active Window 瀏覽器擴充,讓網頁「偵測 inactive」的各種機制無效。 實測確實有用,不過產品本身不盡完善,例如無法調整開關時機(例如只對 Facebook 開啟),副作用不小。

旁門左道 user script

爬了網頁原始碼,發現某個內部細節可以利用,實測一陣子有效,就放出來記錄。
不過臉書隨時改版就可能壞掉,能撐一天是一天。

Script 放在 Greasy Fork → Facebook 不要自動重新整理
原始碼也有放在 GitHub

萬一壞掉時的例外處理,會出現如下畫面(網頁左下角的提示框)

例外處理畫面,版本 1.0.0

講完了,談其他臉書激怒人 UI

Facebook 故意的吧,為了營業目標,讓使用者痛苦也無所謂。

  • 留言被過濾,無法預設顯示「所有留言」

    留言點開時,預設會是「最相關」排序,也就是會被過濾而看不到所有留言。

    介面還會顯示

    你選擇了「最相關」,因此系統可能已過濾掉部分留言。
    不是啊,根本沒得選擇啊!

    留言點開時,顯示已選擇「最相關」所以被過濾 甚至有時明明有 N 則留言,點開卻顯示 0 則

    使用者無法調整,只能每篇文章點開後,再手動改成「所有留言」。

    這樣做 Facebook 可以控制留言的可見性,而每次有人點「所有留言」時,也能拿這些回饋了解使用者行為。

    已知有一些 user script 解方,例如 FB全部留言小幫手FB 預設使用所有留言,基本上都要偵測頁面出現「最相關」之類字眼,再模擬點選「所有留言」的動作。 因為某種「維護起來太苦了」的感受,我目前是沒有使用的。

  • Reels(短影片)沒有控制元件

    短影片沒有進度條可以拉,只能從頭看到完。

    短影音的服務基本上都是這樣,本來就不是要給人方便取得資訊。 對策就是不要看,然而 Facebook 硬推的東西,使用者是無法拒絕的。

    清理垃圾內容的武器,目前看起來比較厲害的是 zbluebugz/facebook-clean-my-feeds,實作也是辛苦地剖析網頁,所以我也還沒嘗試。

    目前只有簡單用 UserCSS 擋一些東西而已:

    @-moz-document domain("www.facebook.com") {
      /* Reels(連續短片和短片)不要顯示(只隱藏內容,標題關不了) */
      div[aria-label='連續短片'][role='region'],
      div[aria-label='Reels'][role='region'],
      div[aria-label='Reel'][role='region'] {
        outline: 3px solid red;
        display: none;
      }
    
      div[aria-label='限時動態'] {
        display: none;
      }
    }
    

偵測「請輸入代號……」就自動送帳密,太過方便了,送出敏感資訊時,還是經過人手操作卡一道比較好。

執行畫面

Script 放在 Greasy Fork → PTT 半自動登入
原始碼也有放在 Github


現有的自動登入方案

這邊說的 PTT 是指 https://term.ptt.cc/,採用修改版 PttChrome(登入後按右鍵「關於」就能看到)在網頁上提供類似純文字介面的操作,是官方維護、使用者眾的服務。當年上線消息:[公告] 使用瀏覽器直接連線至批踢踢

BBS 沒有自動登入功能,早期都是靠連線軟體(例如 PCMan)的自動回應,看見「請輸入代號……」就自動回答。

當直接用瀏覽器上站變成主流,需求就落到擴充套件或 user script 上。 參考一些目前解法:

  1. term.ptt autologin by swstar / 2017

    實作是把 window.WebSocket 換掉以便在 open handler 送出帳密。

  2. term.ptt.cc 自動登入 by maple3142 / 2018

    除了登入,還提供自動跳過一些畫面的功能。 實作是捕捉 PttChrome 的 console 輸出(loginfo),解析訊息判斷發生什麼事,再做反應。

  3. PttChrome+term.ptt.cc Add-on by alan23273850 / 2019

    功能眾多,自動登入只是其一。 實作是比對畫面 innerText 做自動回應。

    這幾支 user script 有一個共通限制,就是要把帳密直接寫在 script 裡才能使用。

  4. PTT Auto Login by c910335 / 2021

    這個不是 user script 而是 Chrome 擴充,利用瀏覽器的密碼管理員儲存/取得密碼,終於不必再寫死帳密了。

    但 Firefox 由於未支援 PasswordCredential,所以是不能用的。


新路數

「如果登入表單是一般 HTML <form>,應該就能沿用密碼管理員了吧?」

之前雖然想過,但一直沒試成功,最近用 <dialog> 避開跟 PttChrome 介面打架,場景乾淨之下就試出來了。

不過只有 Firefox 成功,Chrome 就無法讓密碼管理員跳出來(詢問要不要存密碼),所以 Chrome 的話會退回 PasswordCredential 解法。

實際使用上,只要做一次表單登入並儲存密碼,之後每次登入就只要按 Enter 即可。
如果臨時不想登入,也可以把對話框關掉,就回歸一般使用。


特色總結

  • 不要在 script 內文寫明帳號、密碼
  • 使用瀏覽器的密碼管理員
  • 支援 Firefox(測過版本 126.0.1)
  • 按下「送出」或 Enter 才真正執行登入

用手機點 www. 開頭的 momo 連結,會自動跳到手機版網址(m. 開頭); 但如果在桌面環境點手機版連結,就不會轉換,而是停在手機版,用起來很不舒服。

雖然網頁底部有「電腦版」連結(如圖紅色箭頭處),但它竟然是連到首頁,而不是現在頁面的「電腦版」。
你自己把網址的 m 改成 www,也沒用!因為兩邊網址不能直接對應,又會跳回首頁。

momo 手機版畫面,上圖是一進去的樣子,下圖是網頁底部

這個問題年代已久,網路可以找到一些自救方法,例如 user script Google搜尋顯示桌面版網站,或 Chrome 擴充功能 momo購物轉址

我要的功能比較像那個 Chrome 套件,但需要跨瀏覽器,所以另外寫了一支 user script,
放在 Greasy Fork → momoshop.com.tw 切換手機/電腦版
原始碼也有放在 Github

目前只支援「搜尋」和「商品」兩種頁面。
單純偵測網址,然後顯示一顆「切換至桌面版」按鈕,長相如下圖:

生效中的畫面