goose3 không hề trả về boilerplate có nhãn. Nó còn hai lần trả về trống.

Cập nhật lần cuối vào August 17, 2026
goose3 không hề trả về boilerplate có nhãn. Nó còn hai lần trả về trống.
Tóm tắt bằng AI
Trong các bộ fixture mà việc rò rỉ có thể xác định được, goose3 đạt độ chính xác token nội dung 1.0000 và không có token gây nhiễu. Không một từ nào từ menu, quảng cáo, sidebar, bình luận hay khuyến mãi lọt vào đầu ra. Trong so sánh giữa sáu thư viện, không có thư viện nào làm được điều tương tự. Tuy nhiên, đây cũng là thư viện có độ bao phủ bài viết thấp nhất trong bộ — 0.8243 trên cả 22 fixture, so với 1.0000 của Mozilla Readability — vì ở hai fixture, nó trả về chuỗi rỗng. Hai chỉ số này gắn với nhau theo quy tắc chấm điểm: kết quả rỗng không đóng góp gì cho precision có điều kiện, còn recall thì ghi nhận phần bị bỏ lỡ.

Trong các bộ fixture mà việc “rò rỉ” nội dung có thể xác định được, goose3 đạt độ chính xác token nội dung 1.0000 và 0 token gây nhiễu. Không một từ nào từ menu, quảng cáo, sidebar, bình luận hay khuyến mãi lọt vào đầu ra. Trong so sánh giữa sáu thư viện, không có thư viện nào làm được điều tương tự.

Tuy nhiên, đây cũng là thư viện có độ bao phủ bài viết thấp nhất trong bộ — 0.8243 trên cả 22 fixture, so với 1.0000 của Mozilla Readability — vì ở hai fixture, nó trả về chuỗi rỗng.

Hai chỉ số này gắn với nhau theo quy tắc chấm điểm: kết quả rỗng không đóng góp gì cho precision có điều kiện, còn recall thì ghi nhận phần bị bỏ lỡ.

goose3 là gì

goose3 là bản tiếp nối bằng Python 3 của một dòng công cụ bắt đầu từ Goose của Gravity Labs viết bằng Scala, sau đó qua python-goose. Đây là bộ trích xuất bài viết có kèm metadata, không phải công cụ dump text: khởi tạo Goose, gọi extract(), và bạn sẽ nhận lại một đối tượng Article với khoảng hai mươi tám trường có thể truy cập — text đã làm sạch, tiêu đề, tác giả, ngày xuất bản, ảnh đại diện, meta description, tag, link, tweet, v.v.

Tham khảo chính thức: kho lưu trữ chính thức của goose3.

System diagram: From HTML to Article Fields

Phiên bản được kiểm thử: 3.1.22, giấy phép Apache, 912 sao GitHub, lần đẩy cuối 2026-07-23 — vẫn được duy trì tích cực tại thời điểm kiểm thử. Python 3.14.2.

API chỉ gồm hai lời gọi và một lưu ý bắt buộc:

from goose3 import Goose
g = Goose()
try:
    article = g.extract(raw_html=html)
    text = article.cleaned_text
finally:
    g.close()          # đóng rõ ràng sau khi dùng

close() đáng lưu ý vì rất dễ quên và không có cảnh báo nào. Bài review này không chạy probe theo vòng lặp để định lượng phiên, kết nối hoặc bộ nhớ còn giữ lại khi bỏ qua việc đóng, nên nói “rò rỉ tài nguyên” sẽ mạnh hơn bằng chứng hiện có. Hãy xem việc đóng tường minh là yêu cầu vòng đời được thể hiện qua cách dùng API ở đây.

Đánh đổi, được đo bằng số liệu

Sáu bộ trích xuất, một bộ fixture có gắn nhãn, một bộ chấm điểm. Mỗi khối trong mỗi fixture được gắn nhãn article hoặc boilerplate và có một token sentinel riêng, nên câu hỏi “nó có lấy lại đúng đơn vị này không” được xác định bằng sự xuất hiện của chuỗi con chính xác, chứ không phải bằng điểm tương đồng.

Thư việnRecall bài viết (tất cả 22)Rò rỉ boilerplateĐộ chính xác token nội dungToken gây nhiễuĐầu ra được tạo
Readability1.00000.23530.91093522/22
trafilatura0.98650.05880.9411422/22
newspaper4k0.98650.00000.9452022/22
resiliparse0.90540.05880.9381722/22
jusText0.83780.47060.87607419/22
goose30.82430.00001.0000020/22

sixway-scores.json. Recall được tính trên cả 22 fixture; leak rate và precision được tính trên 11 fixture có cả article lẫn boilerplate.

Khi đọc cột precision, luôn phải nhìn cùng cột cuối. Precision ở đây là có điều kiện theo việc có xuất ra đầu ra — thư viện nào trả về chuỗi rỗng trên một fixture thì không đóng góp gì cho tử số cũng như mẫu số, nên việc im lặng bị “miễn phí” trong trung bình này. Tử số là phần giao giữa tập token không phải stopword được trích xuất và token article đã gắn nhãn; mẫu số là toàn bộ token không phải stopword được trích xuất. “Token gây nhiễu” thì hẹp hơn: chỉ phần giao với token boilerplate đã gắn nhãn. Một token được trích ra nhưng không khớp article lẫn boilerplate sẽ làm precision giảm mà không làm tăng số token gây nhiễu; các token lặp vượt quá đa tập token của article cũng có thể gây ra điều tương tự. Vì thế newspaper4k có thể hiển thị 0 token gây nhiễu nhưng precision vẫn dưới 1.0000. goose3 đạt 1.0000 trên 10 trong 11 fixture được tính; Readability, trafilatura, newspaper4k và resiliparse đều được tính trên 11/11.

Mốc 1.0000 vẫn có giá trị trong bộ synthetic này. Trên mười fixture đã được tính, goose3 không xuất ra bất kỳ token boilerplate nào; Readability xuất ra 35 token trên cùng các trang đó. Nếu một mô hình tiêu thụ đầu ra này, điều đó có nghĩa là không có token nào dành cho boilerplate trong mười fixture ấy. Tuy nhiên, nó không chứng minh là không có lãng phí trên trang thực, và một kết quả rỗng có thể làm phát sinh chi phí fallback hoặc retry ở chỗ khác trong pipeline.

Hai lần im lặng, và ý nghĩa của chúng

goose3 trả về không có gì trên đúng hai fixture. Một fixture có thể chấp nhận được, còn fixture kia là một giới hạn thực sự.

Tài liệu gần như rỗng. Một trang chỉ có một đơn vị bài viết dài 32 ký tự. goose3 từ chối. jusText cũng vậy. Trong bộ fixture này, Readability vẫn trả đầu ra trên cả 22 trang, nên kết quả của nó không ủng hộ việc goose3 im lặng ở đây. Việc từ chối một tài liệu nhỏ như vậy có chấp nhận được hay không phụ thuộc vào hợp đồng tối thiểu về nội dung của bên gọi.

System diagram: Treat Empty Output as Failure

Bài viết được tạo hoàn toàn từ các phần tử <li>. Sáu đơn vị article, không có đơn vị nào nằm trong thẻ <p>. goose3 trả về chuỗi rỗng.

Điều này làm tôi ngạc nhiên, vì cấu hình mặc định của goose3 có parse_lists=True. Nên tôi đã kiểm tra — ba cấu hình, so với một control hoạt động tốt, vì một lần chạy không sinh kết quả không thể nói lên điều gì chắc chắn về cả thư viện:

Cấu hìnhTrang chỉ có danh sáchControl với <p>
mặc định0 ký tự937 ký tự
strict=False0 ký tự937 ký tự
parse_lists=True (chỉ định rõ)0 ký tự937 ký tự

list-only-probe.json.

Cả ba đều là 0, trong khi control luôn trả 937 ký tự. Vậy nên parse_lists=True chỉ quyết định việc các danh sách có được giữ lại bên trong bài viết mà goose3 đã tìm thấy hay không — nó không cho phép bộ chấm điểm ứng viên coi một danh sách chính là bài viết. Cơ chế chấm điểm node của goose3 cần các khối có hình dạng giống đoạn văn để nhận ra phần thân bài, và một trang mà phần thân chỉ là danh sách thì không có khối như vậy.

Kết luận được hỗ trợ bởi dữ liệu là hẹp hơn: một phần thân bài được tạo theo kiểu fixture synthetic này — sáu đơn vị article, đều là <li>, không có ứng viên đoạn văn — đã trả về chuỗi rỗng. Các changelog, tài liệu API, công thức, trang FAQ và bài so sánh là những mẫu rủi ro hợp lý để replay trên trang thật vì chúng có thể nặng về danh sách, nhưng riêng fixture này chưa chứng minh rằng các nhóm trang đó sẽ thất bại nói chung.

Chuỗi rỗng chỉ có thể được máy phát hiện nếu bên gọi kiểm tra đầu ra không rỗng. Nó dễ chặn hơn so với văn bản nhìn có vẻ hợp lý nhưng không chứa phần nội dung bài viết nào, nhưng vẫn là lỗi âm thầm nếu bạn chỉ giám sát theo exception. Một hệ thống production cần kiểm tra ngưỡng nội dung tối thiểu và có fallback hoặc ghi nhận trang thất bại rõ ràng.

Thực tế khi cài đặt

pip install goose3 kéo về 16 gói và 44.3 MiB trong khoảng 6 đến 9 giây. Import nguội đo trong một subprocess mới: 2.181 s.

Tham khảo chính thức: goose3 trên PyPI.

Thư việnSố góisite-packagesImport nguộiExtraction 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. Mỗi thư viện nằm trong một virtualenv trống riêng, nên không bị ảnh hưởng bởi footprint của thư viện khác.

Giữa về độ nặng và tốc độ. Nó cài và import sạch trên Python 3.14.2, điều không phải thư viện nào trong nhóm này cũng làm được.

Ba mặc định đáng biết trước khi triển khai

System diagram: Three defaults worth knowing before you deploy

Đọc object Configuration được đóng gói sẵn thay vì chỉ xem tài liệu sẽ thấy mười chín thiết lập. Có ba cái sẽ khiến người dùng bất ngờ.

Nó tự khai danh tính. browser_user_agent mặc định là Goose/3.1.22. Nếu bạn để goose3 tự fetch, mọi máy chủ bạn chạm tới sẽ ghi lại tên thư viện và đúng phiên bản của nó. Điều đó trung thực, nhưng cũng là một dấu vân tay. Hãy đặt nó một cách chủ đích hoặc tự fetch HTML rồi truyền raw_html.

Nó trỏ tới một binary của MacPorts. imagemagick_convert_path mặc định là /opt/local/bin/convert và imagemagick_identify_path là /opt/local/bin/identify. Trên máy của tôi thì không có cái nào tồn tại — /opt/local là MacPorts, thứ mà đa số người dùng không cài; Homebrew đặt binary ở /opt/homebrew. Mặc định này vô hại nếu bạn không bật fetch ảnh (enable_image_fetching mặc định là False, khá hợp lý), nhưng nếu bạn bật và kỳ vọng trích xuất ảnh đại diện hoạt động, đây là chỗ nó sẽ lặng lẽ không chạy.

Nó mặc định là tiếng Anh. target_language mặc định là en với use_meta_language=True, nên nó sẽ bám theo khai báo ngôn ngữ của trang khi có và quay về tiếng Anh khi không có. Ổn cho công việc tiếng Anh, nhưng nên đặt rõ ràng nếu dùng cho ngôn ngữ khác.

Các thiết lập còn lại đều hợp lý: parser_class là lxml, http_timeout là 30 giây, strict bật, log_level là ERROR, parse_headers và keep_footnotes bật, images_min_bytes là 4.000.

Bộ nhớ, và HTML lỗi làm gì với nó

Hai hạng mục mà mọi bài review trong đợt này đều ghi là chưa kiểm thử, nay đã được đo.

Bối cảnh stress test rộng hơn nằm ở so sánh bộ nhớ và HTML lỗi của mười thư viện.

Bộ nhớ cư trú đỉnh, qua /usr/bin/time -l, mỗi ô là một tiến trình mới — phần nền import là chi phí của thư viện khi được nạp và ở trạng thái idle, còn mức đỉnh thì bao gồm cả tài liệu.

Thư việnRuntimeNền importĐỉnh 226 KBĐỉnh 10 MB
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. Nền Python và Node không thể so sánh trực tiếp với nhau; trình thông dịch nằm bên trong cả hai.

goose3 có nền 44.1 MiB và đạt đỉnh 398.5 MiB trên tài liệu 10 MB. Nền import của nó đứng thứ ba cao nhất trong số các thư viện Python được hiển thị, điều cần lưu ý nếu triển khai nhạy cảm với cold start.

HTML lỗi. Mười hai tài liệu, mỗi cái hỏng đúng một chỗ — thẻ không đóng, phần tử inline lồng sai, thuộc tính không có dấu ngoặc kép nhưng lại có khoảng trắng, thẻ đóng lạc chỗ, không có <html> gì cả, thuộc tính trùng lặp, tài liệu bị cắt dở giữa thẻ, entity lỗi, một <script> không đóng, khai báo charset nói dối, comment chứa markup, và 600 mức lồng nhau — cộng thêm hai control hợp lệ ở kích thước tương ứng, vì “nó trả về trống” chỉ nói được điều gì đó về mức độ lỗi nếu thư viện cũng không im lặng trên một tài liệu sạch cùng kích thước.

goose3 không ném lỗi trên 0/14 và trả về trống trên 10, khôi phục 2/33 sentinel trên các fixture lỗi (malformed-results.json). Một fixture bị loại khỏi số đếm đó: theo HTML5, mọi thứ sau một <script> chưa đóng đều là nội dung script, nên mất chúng ở đó là đúng, còn khôi phục chúng mới là lệch chuẩn.

Ưu và nhược điểm

Điểm mạnh. 0 token boilerplate đã gắn nhãn trên mười fixture fidelity nội dung mà nó có xuất đầu ra. Có sẵn khoảng hai mươi tám trường bài viết, dù độ chính xác của chúng mới được kiểm kê chứ chưa được chấm điểm. Mặc định fetch ảnh hợp lý (tắt). Cài sạch trên Python 3.14. Đang được duy trì tích cực. Apache-2.0. Kết quả rỗng có thể chặn dễ dàng nếu bên gọi kiểm tra tường minh.

Điểm yếu. Recall bài viết thấp nhất trong bộ, 0.8243, và nguyên nhân hoàn toàn là do trả về trống chứ không phải trả về sai. Một trang mà bài viết được tạo bằng danh sách thì sẽ cho chuỗi rỗng bất kể cấu hình. 44.3 MiB và import nguội 2.2 giây là nặng nếu so với resiliparse ở 21.0 MiB và 15 ms. Cần close(). Hai mặc định trỏ tới những thứ thường sai trên đa số máy.

Ai nên dùng và ai không nên dùng

Nên dùng goose3 khi text trích xuất được đưa vào mô hình hoặc cơ sở dữ liệu mà boilerplate có nhãn gây tốn kém, và các trang là bài viết thông thường với các đoạn văn. Trên bộ fixture này, khi nó trả lời thì không xuất ra token boilerplate có nhãn nào. Bề mặt metadata có sẵn nhưng chưa được xác thực ở đây; độ chính xác của tiêu đề, tác giả, ngày tháng và ảnh cần bộ fixture ground-truth riêng trước khi có thể coi là lợi thế chọn lựa.

Không nên dùng nếu corpus của bạn nặng về danh sách — bạn sẽ nhận chuỗi rỗng mà không có giải thích. Không nên dùng nếu chi phí cold start quan trọng, vì resiliparse import nhanh hơn tới 145 lần. Và cũng không nên dùng nếu bạn cần câu trả lời trên mọi trang, vì “không có câu trả lời” là một kết quả thực sự ở đây: 2 trên 22 fixture, và đều âm thầm theo nghĩa chuỗi rỗng không phải exception.

Một cách ghép đáng thử: dùng goose3 làm chính, rồi fallback khi cleaned_text rỗng hoặc thấp hơn ngưỡng nội dung tối thiểu của bạn. Readability đã khôi phục được toàn bộ article unit trong bộ 22 fixture này, bao gồm cả hai trường hợp rỗng của goose3. Kết quả synthetic này ủng hộ mẫu kiến trúc đó, chứ không phải hứa rằng fallback sẽ không bao giờ bỏ sót trên trang thật.

Khi nào API quản lý được dùng

Bài benchmark này kiểm thử đường raw_html của goose3: HTML đã được lấy trước khi goose3 nhìn thấy nó. goose3 cũng có đường fetch qua mạng riêng, như cài đặt User-Agent cho thấy, nhưng đường đó không được kiểm thử ở đây. Việc render JavaScript và chống bot cũng không được kiểm thử.

Để xem cùng bộ fixture trên cả sáu bộ trích xuất, hãy xem so sánh trích xuất giữa sáu thư viện.

Một dịch vụ quản lý cho fetch/render/extraction, bao gồm cả Thunderbit của chúng tôi, thuộc một ranh giới trách nhiệm khác. Thunderbit không được benchmark trong bài kiểm thử này. Điểm khác biệt ở đây là trích xuất bài viết từ HTML được cung cấp so với một dịch vụ hosted vừa lấy vừa xử lý URL; bài viết này không đưa ra so sánh hiệu năng hay chất lượng theo cùng thước đo.

So sánh công bằng là: tập trường của goose3 cố định và theo kiểu bài viết, hoàn toàn đúng khi trang của bạn là article và sai khi đó là danh sách sản phẩm. Nếu bạn đã có HTML và trang của bạn là bài viết, goose3 là miễn phí và rất gọn.

Với phía hosted, tổng hợp API web scraping tốt nhất của chúng tôi là góc nhìn rộng hơn; với các lựa chọn tự host, xem trụ cột scraper mã nguồn mở. Nếu text sẽ đi vào mô hình, chuyển HTML sang Markdown trong Python sẽ cho thấy chỗ fidelity thực sự bị mất.

Dùng thử Thunderbit để trích xuất dữ liệu web

Có nên dùng goose3 không?

Có, nếu bài viết dạng đoạn văn khớp với khối lượng công việc và bên gọi coi đầu ra rỗng là trích xuất thất bại chứ không phải thành công.

Trên bộ fixture này, goose3 không xuất ra token boilerplate có nhãn nào khi có câu trả lời, nhưng lại trả về hai chuỗi rỗng. Một là trang gần như rỗng, một là phần thân synthetic chỉ gồm danh sách. Đó là một đánh đổi giữa precision và coverage, chứ không phải bằng chứng về “tính khí” toàn cục của sản phẩm.

Nếu recall quan trọng hơn, hãy test một fallback với guard kiểm tra ngưỡng đầu ra tối thiểu. Readability đã khôi phục được mọi article unit trong 22 fixture này; newspaper4k cho thấy 0 rò rỉ token boilerplate có nhãn và recall 0.9865, đồng thời xuất đầu ra trên cả 22 trang. Những kết quả đó chỉ xếp hạng cho bộ synthetic này ở trạng thái mặc định, không nói gì về workload production chưa biết.

goose3 xứng đáng có chỗ đứng khi cái giá của một từ sai cao hơn cái giá của một trang bị mất.

Dùng thử Thunderbit để trích xuất dữ liệu web Get Started Free

Câu hỏi thường gặp

Precision hoàn hảo của goose3 là thật hay chỉ là do nó từ chối? Cả hai, và có thể tách riêng. Nó được chấm trên 10 trong 11 fixture có boilerplate, nên một fixture bị thiếu khỏi trung bình — phần đó là hệ quả của việc từ chối. Nhưng trên mười fixture đó, nó trả về 0 token gây nhiễu trước boilerplate được thiết kế đối kháng, trong khi Readability rò rỉ 35 token. Precision là thật với những trang mà nó trả lời; recall là nơi việc từ chối lộ ra.

Vì sao goose3 không trả gì trên trang mà bài viết chỉ là danh sách? Bộ chấm điểm ứng viên của nó cần các khối có hình dạng giống đoạn văn để xác định thân bài, và một trang xây bằng <li> thì không có khối như vậy. Mặc định parse_lists=True không thay đổi điều này — tôi đã thử rõ ràng, thêm strict=False, và đều nhận 0 ký tự ở cả ba cấu hình, trong khi control dùng <p> luôn trả 937 ở cả ba. parse_lists chỉ quyết định việc danh sách có được giữ lại trong bài viết sau khi bài viết đã được tìm ra hay không.

Tôi có phải gọi close() không? Có, hãy đóng tường minh bằng try/finally như ví dụ ở trên. Bài review này không đo xem có gì tích tụ khi bỏ qua việc đóng, nên không khẳng định có rò rỉ theo vòng lặp một cách định lượng; nhưng nó chứng minh rằng Goose có một vòng đời mà bên gọi phải tự quản lý.

goose3 gửi User-Agent gì? Mặc định là Goose/3.1.22 — tức tên thư viện và đúng phiên bản. Điều đó chỉ xảy ra khi bạn để nó tự fetch; nếu truyền raw_html thì hoàn toàn không dùng. Nếu để nó fetch, hãy đặt User-Agent một cách chủ động; mặc định sẽ nói cho mọi máy chủ bạn chạm tới biết chính xác ai đang gọi.

Bài review này không kiểm thử gì? Không kiểm thử trang thực tế, hoàn toàn — đây là các fixture có kiểm soát. Không kiểm thử trích xuất đa ngôn ngữ, dù target_language là một thiết lập hạng nhất. Các trường metadata (tiêu đề, tác giả, ngày tháng, ảnh đại diện) mới chỉ được kiểm kê chứ chưa được chấm chính xác. Không kiểm thử fetch ảnh, vốn tắt theo mặc định và lại trỏ các đường dẫn ImageMagick sang một trình quản lý gói mà đa số máy không có. Không kiểm thử hành vi bộ nhớ khi chạy đồng thời hoặc tải liên tục, cũng như throughput dưới tải; bảng bộ nhớ chỉ đo một tiến trình mới xử lý một tài liệu.

Ke
Ke
CTO tại Thunderbit | Chuyên gia Khoa học Dữ liệu cấp cao & ML Với gần một thập kỷ kinh nghiệm trong học máy và khoa học dữ liệu, Ke Shen là cựu sinh viên Đại học Columbia và từng là Chuyên gia Khoa học Dữ liệu cấp cao tại Walmart Labs. Sở hữu chuyên môn sâu về Python, R, Java và Thống kê, được đồng nghiệp công nhận, anh chia sẻ những góc nhìn thực chiến về cách đưa các thuật toán AI phức tạp từ lý thuyết vào kiến trúc sẵn sàng cho môi trường sản xuất.
Mục lục
Thunderbit · Tác nhân dữ liệu web AI

Trích xuất dữ liệu từ bất kỳ trang nào trong 1 lần nhấp

Được hơn 250.000+ người dùng tin tưởng
có gói miễn phí
Từ trang web đến bảng tính
Mô tả điều bạn cần — AI Agent của Thunderbit sẽ scrape và xuất sang Excel, Google Sheets, Airtable hoặc Notion. Bắt đầu miễn phí.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week