jusText 在短段落測試中的閾值斷崖

最後更新於 August 17, 2026
jusText 在短段落測試中的閾值斷崖
AI 摘要
在一份最長段落只有 151 個字元的文件上,jusText 以預設設定回傳 0 個字元。不是只抓到一部分,而是完全空白。只要把其中一個閾值往下調,讓剛好有一個段落跨過門檻,同一份文件就會輸出 832 個字元。再繼續降低,結果仍然是 832。這個樣本呈現的是懸崖式變化,而不是平滑曲線。預設值是否站在錯的那一邊,取決於目標語料中的段落長度與模板文字分布。若你的語料是多語言,建議評估 jusText,因為它的語言專屬停用詞表面很明確,也很廣。

在一份最長段落只有 151 個字元的文件上,jusText 用預設設定回傳 0 個字元。不是只抓到一點點,而是整頁直接空白。只要把其中一個閾值往下調,讓剛好有一個段落跨過門檻,同一份文件就會輸出 832 個字元。再繼續降低,結果還是 832。

在這個測試樣本裡,整體行為比較像是懸崖,不像斜坡。預設值到底站對邊還是站錯邊,完全取決於你的語料裡段落長度和模板文字的分布。

什麼是 jusText,為什麼詞彙密度這麼重要

和這組測試中的其他抽取器相比,jusText 對 語言專屬停用詞密度 的依賴特別高。一個功能詞比例比較高的區塊——像是 theandofwas——更有可能是正文。這個詞彙訊號不是整個分類器的全部:段落長度、連結密度、從 HTML 推得的區塊邊界、標題距離、相鄰類別,以及一個帶上下文感知的第二輪判定,都會一起影響結果。

官方參考:jusText 官方倉庫

System diagram: Two-Pass Paragraph Classification

因為分類器需要語言停用詞清單,jusText 內建了 100 種。在這次比較裡,這種明確的語言詞彙層是它最鮮明的差異化特徵,不過這次並沒有測多語言品質。

測試版本:3.0.2,BSD 2-Clause,822 個 GitHub stars。Python 3.14.2。

這道斷崖,有多明顯

Measured results chart: Characters returned as length_high changes

jusText 的分類器分兩輪運作。第一輪不看上下文,會把每個段落標成 goodbadshortneargood。第二輪會把 neargood 提升成 good——但前提是它旁邊已經有一個 good 區塊。而一個段落只有在超過 length_high 時,才會單獨拿到 good;預設值是 200 個字元

在一份沒有任何段落超過 200 字元的文件裡,就不會有種子段落可供提升;所有 neargood 區塊最後都會被當成模板文字。整頁結果自然就是空的。

我在一份最長段落只有 151 字元的樣本上掃過這個閾值:

length_high被分類為 good 的段落數回傳字元數
200(預設)00
1508832
1208832
1008832
808832

justext-length-threshold.json

在這個閾值測試裡,只要有一個段落跨過門檻,八個目標段落就會全部被輸出;再繼續放寬也不會多出任何內容。這條軌跡和上下文輪次在既有 good 區塊周圍推進合格 neargood 鄰居的機制一致;它不代表在任意頁面上都會無條件提升所有鄰居。

在把 length_high 當成開關之前,我先把 length_low 掃過四個值,再和 max_link_density 的兩個值交叉測試:8 種組合,全都回傳 0。改這兩個設定,沒辦法在這份樣本上救回輸出。

整個 22 個樣本的集合也呈現同樣模式:length_high=200 時,22 個裡只有 2 個 有輸出;降到 150 時是 9 個;降到 120 時是 15 個

這裡不是在說 jusText 抽取很差——在一個真實的自然語言頁面上、以預設值執行,它回傳了 1,190 個字元 的乾淨文章內容,因為真實新聞段落第一次就能超過 200 字元。它也不是在說預設值一定錯了;它只是表示預設值假設段落夠長,而你在跑之前應該先確認自己的語料有沒有符合這個前提。

這組測試的另一面:預設值下的漏抓更高

在這組標記樣本中、以預設值執行時,jusText 的模板文字漏抓率是最高的。

LibraryArticle recall (all 22)Boilerplate leakContent-token precisionContaminating tokens
Readability1.00000.23530.910935
trafilatura0.98650.05880.94114
newspaper4k0.98650.00000.94520
resiliparse0.90540.05880.93817
jusText0.83780.47060.876074
goose30.82430.00001.00000

sixway-scores.json。同一組樣本、同一個評分器,每個單位都用獨特的標記值標註,因此可精準以子字串方式回收。

System diagram: Leakage and Silence Share a Boundary

47% 的模板文字漏抓率、74 個污染 token——漏抓率是 Readability 的兩倍,污染量也超過兩倍。這是這組標記合成樣本、以預設值得到的診斷結果,不代表穩定的全產品排名。

觀察到的漏抓現象,和前面那道斷崖用的是同一套上下文判定。當周邊區塊類別與距離規則允許時,合格的 neargood 區塊就可能被提升;因此,一段看起來像正文的宣傳文案或留言,如果緊貼文章正文,就有可能跨過邊界。這個樣本結果展示的是哪些標記區塊發生了漏抓,而簡化後的機制還是取決於 jusText 的實際上下文規則。

它的 recall 是 0.8378,排在倒數第三,而損失幾乎都出在門檻:一篇 129 字元的短文章完全沒抓到、十個短段落的頁面也沒抓到、接近空白的文件同樣沒抓到。

語言停用詞清單盤點

另外 99 種停用詞清單。

justext.get_stoplists() 會回傳 100 種語言。這個分類器從設計上就是以語言參數化,而不是只把英文規則翻一翻而已;切換語言只要改一個參數:

import justext
paragraphs = justext.justext(html, justext.get_stoplist("Czech"))
text = "\n".join(p.text for p in paragraphs if not p.is_boilerplate)

trafilatura 和 goose3 也都有跟語言相關的行為,不過這次評測沒有對任何抽取器做非英文真值評分。jusText 內建的 100 套停用詞清單,讓它成為多語言評估的明顯候選;但光看清單數量,不能證明它在那些語言上的抽取品質,也不能證明競品在那些語言上的支援比較差。

這個 API 只有兩個函式和 9 個可調常數:length_low 70、length_high 200、stopwords_low 0.30、stopwords_high 0.32、max_link_density 0.20、max_heading_distance 200,再加上編碼處理。簡潔、好讀,而且都直接寫在函式簽名裡。

安裝與速度

pip install justext 會拉下 3 個套件——在這次比較中是最少的——以及 22.4 MiB,而且不到兩秒就裝好。

官方參考:PyPI 上的 jusText

LibraryPackagessite-packagesCold importExtraction p50
resiliparse521.0 MiB0.015 s0.06 ms
jusText322.4 MiB0.777 s0.56 ms
goose31644.3 MiB2.181 s1.85 ms
newspaper4k2247.5 MiB2.812 s2.69 ms
trafilatura1769.9 MiB1.584 s0.51 ms

install-and-import.json。每個函式庫都在各自空白的 virtualenv 裡測試。

3 個套件和 22.4 MiB 在這次比較中算是很輕量的依賴,而 0.56 ms 的中位數抽取速度,也和這個測試框架裡 trafilatura 的 0.51 ms 很接近。環境量測沒有依檔案類型拆分套件大小,所以無法判斷有多少磁碟占用來自停用詞清單。

維護狀況,要怎麼看才準

這裡採用的「日期偏舊」維護指標,是倉庫最後一次 push 和 PyPI 最後一次 release,兩者都是 2025-02-25。那距離測試時點已經十七個月。總共 8 個版本、91 個 forks、9 個開放 issues,且沒有封存。

PyPI 的 classifiers 最多只標到 Python 3.9。但我在 3.14.2 上執行時,它能正常安裝、0.777 秒完成 import,並在 22 個樣本中的 19 個上完成抽取,沒有任何例外。

所以,metadata 比實際情況落後了五個 Python 版本,而實際情況是它能跑。真正有用的區別在這裡:安靜的倉庫反映的是支援度,不一定代表功能失效。對一個演算法本身就是 2011 年公開方法、再加上一組詞表的函式庫來說,「已經完成」其實很合理——能改的本來就不多,而停用詞清單也不像反爬 workaround 那樣容易失效。

不過,倉庫安靜也代表:如果你真的撞到 bug,很可能要自己修,或者自己 fork。這一點要跟那 9 個開放 issues 一起看;這不是一個問題爆炸、卻完全沒人在處理的典型。

記憶體,以及壞掉的 HTML 會怎麼影響它

這裡分開量兩個營運面問題。

更完整的壓力測試背景,可參考 十個函式庫的記憶體與錯誤 HTML 比較

峰值常駐記憶體 透過 /usr/bin/time -l 取得,每一格都用一個全新程序執行——import 基線代表函式庫載入後閒置時的成本,峰值則包含文件本身。

LibraryRuntimeImport floor226 KB peak10 MB peak
html2textpython3.1418.719.971.2
pyquerypython3.1430.333.9172.5
resiliparsepython3.1420.525.1225.1
markdownifypython3.1423.928.9278.5
goose3python3.1444.152.4398.5
cheerionode2266.876.5398.5
justextpython3.1430.336.6431.2
newspaper4kpython3.1452.661.8668.5
trafilaturapython3.1452.564.8927.1
turndownnode2247.868.42947.1

memory-results.json。Python 和 Node 的基線彼此不能直接比較,因為兩者都包含了解譯器。

jusText 的基線是 30.3 MiB,而在這個 10 MB 樣本上的峰值是 431.2 MiB,大約是 import 基線的 14.2 倍,也相當於輸入大小的 43.1 倍 RSS。單一樣本和單一程序還不足以推導一般性的縮放曲線;Python 和 Node 的基線也仍然不能直接互比。

壞掉的 HTML。 十二份文件各自只壞一個地方——未閉合標籤、錯誤巢狀的 inline 元素、帶空格卻未加引號的屬性、亂入的結尾標籤、根本沒有 <html>、重複屬性、文件在標籤中途被截斷、錯誤的 entities、未閉合的 <script>、說謊的 charset 宣告、包含標記的註解,以及 600 層巢狀——另外再加上 兩份尺寸相符的正常對照,因為「它什麼都沒回傳」只有在同尺寸的乾淨文件也不回傳時,才真的能說明它對錯誤 HTML 很敏感。

justext 在 14 份中的 0 份上拋出例外,並在 13 份上回傳空結果,在這些錯誤樣本中,33 個已評分的 sentinel 完全沒有被恢復出來(malformed-results.json)。那份正常的短對照也回傳 0 字元;正常的長對照則是唯一有內容的結果,輸出 1,333 個字元。十二份錯誤樣本全都保持空白,而未閉合 <script> 的案例不納入 sentinel 存活評分。因此,這批結果可以說明 parser 容忍度——沒有例外——但不能把空白歸因於 HTML 錯誤,而不是前面已經量到的尺寸閾值。

優點與缺點

優點。 100 種語言停用詞清單,而且分類器確實是圍繞這些清單設計,不只是把英文規則翻過去。這次比較裡套件數量最少,只有 3 個。中位數抽取時間 0.56 ms。有 9 個寫得很清楚、可以直接調的常數。BSD 2-Clause。即使 classifiers 只寫到 3.9,也能在 Python 3.14 上順利運作。

缺點。 在這組合成測試的預設值下,模板文字漏抓率最高:47%,還有 74 個污染 token。短段落樣本在沒有任何段落跨過 length_high 時會直接回傳空字串。這組資料的 recall 是 0.8378。最後一次記錄到的倉庫 push 和 release 都是在測試前十七個月,所以維護責任要一起納入考量。

誰適合用,誰不適合

如果你的語料是多語言,值得評估 jusText,因為它的語言專屬停用詞表面很明確,也很廣。這次只盤點了 100 種停用詞清單,沒有衡量多語言品質。若你的部署很在意只依賴 3 個套件,而且希望有明確可控的閾值,這也是它的候選場景。

如果你是要把內容逐 token 丟給模型,那就不建議用它,因為 74 個污染 token 相較於 goose3 和 newspaper4k 的 0,會是直接成本。若頁面多是短段落——例如產品文案、列表、變更紀錄、FAQ 條目——除非你有意調整 length_high,不然也不建議用。若你所在的合規或採購環境需要一個仍在積極維護的依賴,也應該跳過;就算程式能跑,這還是現實上的限制。

**如果你真的要用,**請拿帶標記的驗證樣本去調 length_high,不要照抄預設值,也不要直接套分位數規則。把可能的閾值都掃一次,分別量 article recall 和 boilerplate precision;把門檻調低雖然可能救回短正文,但也可能把不該進來的鄰近區塊一起放進來。

什麼情況下適合改用代管 API

jusText 只處理你已經拿到的 HTML,這點和這次比較裡所有工具都一樣。它們都不會幫你抓頁面、不會渲染 JavaScript,也不會處理反爬層。

若要看六個抽取器在相同樣本上的比較,請參考 六個函式庫的抽取比較

像我們自己的 Thunderbit 這類代管的抓取/渲染/抽取服務,負責的是另一個層級的工作。這次沒有把 Thunderbit 納入基準測試。兩者的差別在於:一邊是對已提供的 HTML 做正文分類,另一邊是負責取得並處理網址;這篇文章並沒有提供可直接對照的同指標品質比較。

老實說,jusText 的多語言停用詞清單確實是一項真本事,而且是免費的。如果你的問題是要抓取多語言頁面,而不是分類那些頁面的正文,那你需要買的是另一種東西。

若想看更完整的市場版圖,可參考我們的 web scraping API 總覽 了解代管方案,或看 開源爬蟲主題頁 了解自架方案。如果輸出要送進模型,用 Python 把 HTML 轉成 Markdown 往往就是資訊流失最多的地方。

試用 Thunderbit 進行網頁資料擷取

是否該使用 jusText?

如果你的語料是多語言,或段落長度分布能受惠於明確的閾值調整,它可以列入候選。正式上線前,先驗證這兩點。

內建的 100 套停用詞清單是它真正的設計特色,但多語言準確度並沒有在這裡測試。這道閾值斷崖是可調的;低一些是否可接受,取決於在標記樣本上測得的 recall 和 boilerplate precision。

在這組英文合成樣本、以預設值執行時,newspaper4k 沒有漏掉任何標記模板文字,並回收了 0.9865 的文章單位。這讓它成為這個工作負載裡的比較候選,但不是適用所有場景的通用替代建議。

試用 Thunderbit 進行網頁資料擷取 Get Started Free

常見問題

為什麼 jusText 會回傳空字串,而不是部分抽取結果? 它的分類器分兩輪運作。段落只有在超過 length_high(預設 200 字元)時,才會單獨拿到 good 類別;第二輪才會把鄰近的 neargood 區塊往上提。如果沒有任何段落跨過門檻,就不會有種子,所有候選都會退回成模板文字,所以結果會是空的。這是設計上的全有或全無,不是只找到一部分答案。

jusText 已經沒人維護了嗎? 最後一次倉庫 push 和最後一次 PyPI release 都是在 2025-02-25——距離測試時點十七個月——而且 PyPI classifiers 最多只寫到 Python 3.9。不過它在 Python 3.14.2 上安裝和執行都沒有例外,而且 9 個開放 issues 也不算太多。日期應該解讀成維護風險,而不是功能壞掉的證明;實際風險比較像是你可能得自己修自己的 bug。

為什麼它比 Readability 更容易漏抓模板文字? 在這組樣本中,預設上下文規則讓看起來像正文的鄰近區塊跨過了輸出邊界。是否被提升,取決於區塊類別、距離與上下文,而不是每個鄰居都會自動通過。量到的結果是在預設值下有 47% 的模板文字漏抓率,以及 74 個污染 token。

要怎麼把它用在其他語言? justext.justext(html, justext.get_stoplist("German"))get_stoplists() 會回傳全部 100 種可用清單。停用詞清單是這個分類器的語言詞彙輸入,但它同時也會用到段落長度、連結密度、從 HTML 推得的分段、標題距離和鄰近區塊上下文。這只是在改語言輸入;不能只靠這一步就證明德文抽取品質。

這裡沒有測試什麼? 沒有測真實世界頁面——這些都是有標記單位的受控樣本。也沒有測多語言能力;那本來就是這個函式庫的主打特色,雖然我們盤點了 100 套停用詞清單,但沒有對非英文文本評分。也沒有測編碼邊界條件,儘管 jusText 提供了 encodingdefault_encodingenc_errors 參數。而 max_heading_distance 以及兩個停用詞比例閾值,全都在整個測試中維持預設值。

Ke
Ke
Thunderbit 技術長|資深資料科學家與機器學習專家 Ke Shen 在機器學習與資料科學領域擁有近十年經驗,畢業於哥倫比亞大學,曾任 Walmart Labs 資深資料科學家。他精通 Python、R、Java 與統計學,且具備深受同儕認可的深厚專業,分享如何將複雜的 AI 演算法從理論落實到可投入生產的架構的實戰見解。
目錄
Thunderbit · AI 網頁資料代理

1 次點擊 內擷取任何頁面的資料

獲 250,000+ 用戶信賴
提供免費方案
從網頁到試算表
描述你需要什麼——Thunderbit 的 AI Agent 會幫你抓取並匯出到 Excel、Google Sheets、Airtable 或 Notion。可免費開始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week