GitHub `pushed_at` הטעה ב-14 מתוך 35 מאגרי scraping; בשלושה אושרו בוטים

עודכן לאחרונה ב-August 14, 2026
GitHub `pushed_at` הטעה ב-14 מתוך 35 מאגרי scraping; בשלושה אושרו בוטים
סיכום AI
דף המאגר של GitHub חושף את pushedat — חותמת זמן שיכולה להתעדכן כשיש push לכל ענף שהוא. לכן היא עלולה להיות שונה מה-commit החדש ביותר בענף ברירת המחדל. התאריך של ענף ברירת המחדל הוא אות לתחזוקת המאגר; הוא לא בהכרח הקוד שמותקן דרך מנהל חבילות. בדרך כלל מנהלי חבילות פותרים ארטיפקטים מהרישום או גרסאות של מודולים. לכן הבדיקה הזאת מפרידה בין פעילות המאגר לבין הארטיפקט שפורסם: אחד מהם יכול להיות עדכני בזמן שהשני מיושן. אז משכתי 35 מאגרים שעדיין מופיעים בהמלצות, ובדקתי את המספר ש-GitHub לא מציג בכותרת: התאריך של ה-commit החדש ביותר בענף ברירת המחדל.

דף המאגר של GitHub מציג את pushed_at — חותמת זמן שיכולה להתעדכן בכל פעם שיש push לכל ענף שהוא. לכן היא יכולה להיות שונה מה-commit האחרון בענף ברירת המחדל. התאריך של ענף ברירת המחדל הוא סימן לתחזוקת המאגר; הוא לא בהכרח הקוד שמותקן דרך מנהל חבילות.

בדרך כלל מנהלי חבילות פותרים ארטיפקטים מהרישום או גרסאות של מודולים. לכן הבדיקה הזאת מפרידה בין פעילות המאגר לבין הארטיפקט שפורסם: אחד מהם יכול להיות עדכני בזמן שהשני כבר מיושן.

אז משכתי 35 מאגרים שעדיין מופיעים בהמלצות, ובדקתי את המספר ש-GitHub לא מציג בכותרת: התאריך של ה-commit החדש ביותר בענף ברירת המחדל.

הפער אמיתי: ב-14 מתוך 35, הערך של pushed_at מתקדם ביותר מ-180 יום מעבר ל-commit האחרון בענף ברירת המחדל, עם שיא של 1,802 ימים. בשלושה מתוך 14 האלה אושרו בוטים באופן חיובי; אחרי סינון מאגרים בארכיון ופעילות אנושית, נשארו שני מקרי בוט מאומתים מתוך תשעה מועמדים. המסקנה השימושית יותר היא שתאריך המאגר ותאריך הארטיפקט שפורסם יכולים להתפצל.

מה נמדד, ועל בסיס מה

System diagram: What was measured, and on what

הפניה רשמית: GitHub repository API.

כל מספר כאן נקרא מתשובת API חיה בין 15:44 ל-15:53 UTC ב-2026-07-27 ונשמר במטמון. מערך הנתונים בן 35 השורות, רשימת המאגרים, השורות שנבנו, וסקריפטי המשיכה/הבנייה ב-artifacts/ שומרים את קלטי הבדיקה ואת קוד הטרנספורמציה.

נאספו ארבע קטגוריות נתונים; בקשות לרישום ולפעילות נעשו באופן מותנה ולא כסדרה אחידה של ארבע קריאות:

  • GET /repos/{owner}/{repo} — כוכבים, archived, pushed_at, רישיון, default_branch.
  • GET /repos/{o}/{r}/commits?sha={default_branch}&per_page=1 — ה-commit החדש ביותר בענף ברירת המחדל, שמשמש כאות לתחזוקת המאגר.
  • GET /repos/{o}/{r}/activity?per_page=30 — בכל מאגר שבו שני הערכים האלה לא תואמים, מה באמת הזיז את pushed_at.
  • GET /repos/{o}/{r}/releases יחד עם הרישומים של PyPI ו-npm — מתי הארטיפקט עצמו שוחרר לאחרונה, ומתברר שזה חשוב יותר מכל אחד מהם.

staleness_days הוא הזמן שחלף מה-commit בענף ברירת המחדל עד רגע המדידה. הפער בין pushed_at לבין ה-commit הזה הוא האשליה, ונמדד בימים. כל דבר מעל 180 יום מסומן.

שני עקרונות חשובים כאן, כי הם שינו את התוצאות.

שיוך חבילות אומת, ולא הוסק. חבילה שה-README שלה מזכיר מאגר אינה בהכרח החבילה של אותו מאגר. כל מיפוי הוכרח לעמוד בשדה מובנה — הערך repository/project_urls של הרישום עצמו, או manifest שמופיע בתוך המאגר. שישה מיפויים שנראו סבירים נכשלו בבדיקה הזאת, וספירת ההורדות שלהם לא שויכה בכוונה.

אחד הדחיות האלה לבדו מצדיק את הכלל כולו. curl-cffi מושך 35,763,529 הורדות בחודש ונראה מרחוק כמו ה-binding של Python עבור lwthiker/curl-impersonate — מאגר שקפוא כבר 875 ימים. שיוך כזה היה מייצר מספר גדול פי ארבעים וארבע מ-newspaper3k, והוא היה שגוי: המטא-דאטה של PyPI עבור curl-cffi מפנה ל-lexiforest/curl_cffi, פרויקט נפרד ומתוחזק שפורסם לאחרונה ב-2026-04-03. המספר המרשים ביותר כאן היה דווקא הלא נכון.

מקרה שביעי הוא מוזר עוד יותר: steel-dev/steel-mcp-server מצהיר על @steel-dev/mcp-server ב-package.json שלו, אבל npm מחזיר 404. הוא מעולם לא פורסם, ולכן אי אפשר לומר עליו שהוא "עדיין מותקן".

כשאי אפשר להשיג מספר, זה מצוין כך. כלים ב-Go, JVM, .NET ו-PHP אינם נוכחים ב-PyPI או ב-npm, ולכן הם מסומנים כ-N/A (no PyPI/npm package) — לעולם לא כאפס. 17 מתוך 35 לא מפרסמים GitHub Releases בכלל; זה נרשם כ-none, ולא כנתון חסר.

השדות האלה לא קובצו בכוונה לציון בריאות יחיד. ענף ברירת מחדל מיושן, ענף צדדי עדכני, היעדר GitHub Release, וארטיפקט ישן ברישום עונים על שאלות שונות. ראיות ברמת שורה זמינות ב-מערך הנתונים בן 35 השורות, יחד עם קלטי המאגרים ו-הרשומות שנבנו. יש לקרוא אותם כאיתורי מיון שמכוונים לבדיקה הבאה, לא כהצבעה ארבע-כנגד-אחד בשאלה אם פרויקט חי.

אזהרת הדגימה, כבר בהתחלה

זו רשימה ידנית של כלים שחשדתי שהם חיים על מוניטין. זו לא דגימה אקראית של אקוסיסטם scraping, ו-"31 מתוך 35 מיושנים" הוא לא שיעור אקוסיסטם — זה קרוב יותר למדד של כמה טוב בחרתי. התוצאה המעניינת אינה ספירת המיושנים. היא שגם בדגימה שנבחרה בגלל התופעה, המנגנון הספציפי שבדקתי הסביר רק מיעוט מהמקרים, ובאופן חיובי ניתן היה לאשר אותו בפחות מאלה.

האשליה אמיתית, וזה המקרה הקיצוני ביותר שלה

sjdirect/abot, סורק .NET עם 2,308 כוכבים. GitHub מציג push ב-2026-07-17, עשרה ימים לפני תאריך המדידה. אבל הענף הראשי עודכן לאחרונה ב-2021-08-09.

זה פער של 1,802 ימים. חמש שנים. הכותרת אומרת "בשבוע שעבר".

ב-14 מתוך 35 המאגרים יש פער של יותר מ-180 יום:

RepoGap (days)Default branch last movedpushed_at
sjdirect/abot1,8022021-08-092026-07-17
dragnet-org/dragnet1,5202021-05-092025-07-08
paquettg/php-html-parser1,3762020-11-012024-08-09
seomoz/simhash-py1,1592020-03-122023-05-15
internetarchive/wayback1,0392021-04-272024-03-01
Rhizome-Conifer/conifer1,0132023-10-122026-07-22
kohlschutter/boilerpipe8562015-08-302018-01-03
scrapinghub/splash8192022-05-052024-08-02
tomnomnom/waybackurls7562022-04-052024-05-01
geziyor/geziyor6892024-08-122026-07-02
crawlab-team/crawlab4882024-10-092026-02-10
ArchiveTeam/wpull4682023-01-162024-04-29
yasserg/crawler4j3962020-10-032021-11-04
apache/any233812022-06-032023-06-20

14 מתוך 35. אמיתי, חשוב לדעת, ומיעוט מתוך דגימה שנבחרה כדי להכיל אותו.

בוטים אושרו בשלושה מאגרים מסומנים — ושניים נשארו לאחר סינון

הגרסה העממית של הסיפור תמיד מזכירה את dependabot. בדקתי זאת באמצעות משיכת פיד הפעילות של כל מאגר מסומן וסיווג כל ref שנדחף אחרי ה-commit האחרון בענף ברירת המחדל. ה"אחרי" הזה חשוב: אירועים שקדמו ל-commit האחרון לא אומרים דבר על מה שהגדיל את הפער, וספירת כל הפיד משנה בשקט את השאלה.

אושר כמונע-בוט, בשיטת אחרי-ה-commit: שלושה. scrapinghub/splash (4 מתוך 4 אירועים אחרי commit על dependabot/pip/*), geziyor/geziyor (5 מתוך 5 על dependabot/go_modules/*), apache/any23 (16 מתוך 16 על dependabot/maven/*). אחד מהשלושה האלה, any23, מסומן רשמית כ-archived, ולכן הוא בכלל לא נכנס לקבוצת המסוננים — מה שמשאיר שני מקרי בוט מאומתים שגם עומדים בכל התנאים האחרים.

שגוי לחלוטין: שניים, ושניהם מעניינים יותר מסיפור הבוט.

הפער של 1,520 יום ב-dragnet-org/dragnet נובע מאדם שדחף ענף בשם mp/py3.10 — פורט ל-Python 3.10 שלא מוזג. מישהו ניסה לקדם אותו ועצר. זו לא רעש אוטומטי שמנפח חותמת זמן; זו תיעוד גלוי ומתוארך של ניסיון הצלה שנכשל. אפשר לטעון שזה דווקא האות השימושי ביותר בכל מערך הנתונים, והמסגור של "dependabot עשה את זה" היה מוחק אותו.

מעורב, וגדול יותר מכל אחד מהם: שניים. ל-crawlab-team/crawlab יש 12,250 כוכבים — השני בגודלו בדגימה — ופער של 488 יום על main. הפיד שלו כולל ענפי dependabot וגם 24 pushes אחרי commit מצד בני אדם, כולם ל-develop ול-test. משתמש שרואה את הכותרת חושב פברואר 2026 ומניח בריאות; משתמש שקורא את main רואה אוקטובר 2024 ומניח מוות. שני ההנחות שגויות. הפיתוח עבר מחוץ לענף ברירת המחדל, וזה דבר שפרויקטים עושים ותקציר GitHub פשוט לא יודע לבטא. sjdirect/abot הוא המקרה המעורב הנוסף: ה-push שקבע את pushed_at בכותרת היה באמת של dependabot, אבל אדם דחף upgrade1 ב-2024, ולכן המאגר נופל אחר כך מהקבוצה המסוננת.

Rhizome-Conifer/conifer הוא המקרה העמום, ובהתחלה קראתי אותו לא נכון. ענף ברירת המחדל שלו הוא main, לא master, ו-main לא זז מאז 2023-10-12 — האירוע היחיד של main בפיד הוא יצירת ענף בינואר 2025, דבר שמתאים לשינוי שם. במקביל, חשבון יחיד דחף ל-conifer-twilight ול-twilight/read-only ב-2026-07-22, חמישה ימים לפני מועד המדידה. זו פעילות אנושית אמיתית, אבל "מפותח באופן פעיל" הוא ניסוח רחב מדי ביחס למה שה-refs תומכים בו: תורם אחד, על ענפים בשם read-only, מתאים לפחות כמו סגירה מנוהלת כמו לפיתוח מתמשך. מה שכן אפשר לומר, ובצדק, הוא הצהרה צרה יותר: הפער של 1,013 ימים אינו רעש של בוט, וגם אינו הוכחה לנטישה.

לא ידוע: שבעה. php-html-parser, simhash-py, internetarchive/wayback, boilerpipe, waybackurls, wpull ו-crawler4j כולם מציגים פער מאומת ופיד פעילות שחוזר ריק.

ההסבר המתבקש הוא שמירה על נתונים היסטוריים — פיד הפעילות של GitHub לא מגיע לנצח אחורה. אבל המטמון מפריך זאת ברוב המקרים. האירוע הוותיק ביותר מבין 123 התשובות כאן הוא 2023-03-10, ולחמישה מתוך השבעה יש pushed_at שנמצא בנוחות בתוך החלון הזה: php-html-parser ב-2024-08-09, wpull ב-2024-04-29, waybackurls ב-2024-05-01, internetarchive/wayback ב-2024-03-01, simhash-py ב-2023-05-15. מה שגרם לעדכון החותמות האלה היה אמור להופיע בפיד ולא הופיע. שמירת היסטוריה מסבירה רק את boilerpipe (2018) ואת crawler4j (2021).

לכן הניסוח הכנה דק הרבה יותר מהסבר מסודר: לשבעה מאגרים הפער הוא עובדה מאומתת, והסיבה לו לא הוכחה — ה-endpoint לא החזיר דבר, ולגבי חמישה מהם איני יכול להסביר למה. "dependabot עשה את זה" הוא הנחה לגבי כולם.

בסיכום, מתוך 14 המאגרים המסומנים:

Cause of the inflated pushed_atReposWhich, and on what evidence
Confirmed bot-driven3scrapinghub/splash (4 of 4 post-commit events on dependabot/pip/*), geziyor/geziyor (5 of 5 on dependabot/go_modules/*), apache/any23 (16 of 16 on dependabot/maven/*) — any23 is archived, leaving two that also satisfy every other condition
Mixed, bot and human2crawlab-team/crawlab (dependabot branches plus 24 post-commit pushes from humans, all to develop and test), sjdirect/abot (the push that set its headline pushed_at really was dependabot, but a human pushed upgrade1 in 2024)
Outright wrong — human work, zero bot branches2dragnet-org/dragnet (3 post-commit events, 0 on a bot branch) — a human pushing mp/py3.10, an unmerged Python 3.10 port. Rhizome-Conifer/conifer (30 post-commit events, 0 on a bot branch) — a single account pushing conifer-twilight and twilight/read-only on 2026-07-22. Whether conifer is abandoned stays ambiguous, as above; what is not ambiguous is that no bot inflated its pushed_at
Unestablished — activity feed empty7php-html-parser, simhash-py, internetarchive/wayback, boilerpipe, waybackurls, wpull, crawler4j

השורות מסתכמות ל-14. הן מסווגות מה הזיז את pushed_at; הן לא קובעות לבדן אם פרויקט נטוש.

מה שורד את הסינון המלא, ומה פירוש "שורד"

הטענה המקורית דורשת ארבעה דברים יחד: מיושן מעל שנה, pushed_at מנופח ביותר מ-180 יום, לא archived, וללא סימן שהניפוח נבע מעבודה אנושית. תשעה מתוך 35 מועמדים עומדים בכל הארבעה, ומופיעים כאן לצד שתי ההחרגות החשובות ביותר:

RepoClears all four?Positive evidence that bots drove the inflation
splashyesyes — 4 of 4 post-commit events on dependabot/pip/*
waybackurlsyesnone in either direction
crawler4jyesnone in either direction
geziyoryesyes — 5 of 5 on dependabot/go_modules/*
php-html-parseryesnone in either direction
boilerpipeyesnone in either direction
wpullyesnone in either direction
internetarchive/waybackyesnone in either direction
simhash-pyyesnone in either direction
any23no — archivedyes — 16 of 16 on dependabot/maven/*, the single strongest confirmation in the whole audit
abotno — its record contains a human push (upgrade1, 2024)mixed — the push that set its headline pushed_at really was dependabot

למספר הזה דרושה הסתייגות שהמסנן לא יכול לשאת. רק שניים מתוך התשעה — splash ו-geziyor — כוללים ראיה חיובית לכך שבוטים אכן גרמו לניפוח. שבעת האחרים עומדים בתנאי הרביעי כי אין ראיות לכאן או לכאן. אלו מקרים שהטענה שורדת בהם, לא מקרים שמאשרים אותה. והאישור החזק ביותר בכל הבדיקה, any23 עם 16 מתוך 16 אירועי dependabot, נפסל משום שהמאגר בארכיון.

שימו לב גם ש-abot, מקרה 1,802 הימים, אינו בין התשעה. הרשומה שלו כוללת push אנושי, ולכן הוא נכשל בתנאי הרביעי — האשליה הדרמטית ביותר במערך הנתונים היא לא מקרה נקי של המנגנון שהיא מדגימה.

עבור 21 מתוך 35, GitHub דיווח בבירור על ה-staleness

הנה הממצא שפגע הכי הרבה בתזה שלי. ל-14 מאגרים יש פער של אפס בדיוק, ועוד שבעה נמצאים מתחת ל-180 יום. עבור 21 מתוך 35 מועמדים, pushed_at הוא ה-commit האחרון בענף ברירת המחדל. GitHub לא מסתיר דבר.

כולל כמה מהדברים המתים ביותר בדגימה:

RepoStarsStale (days)Gap
Janpot/microdata-node571,8660
1e0ng/simhash1,0371,60621
ekzhu/SetSimilaritySearch6031,3840
GerbenJavado/LinkFinder4,4318340
hakluke/hakrawler5,0995820
lavague-ai/LaVague6,3885510
my8100/scrapydweb3,4115220
getomni-ai/zerox12,2584320
scrapinghub/frontera1,3324150
BuilderIO/gpt-crawler22,3743840

ל-BuilderIO/gpt-crawler יש 22,374 כוכבים, והכותרת שלו אומרת אותו דבר מאז 2025-07-07. שום דבר לא מוסתר, וההתקנות ממשיכות.

זה כופה את הטענה לנוסח מצומצם יותר: GitHub מסתיר staleness במיעוט מהמקרים, וברובם הוא מצהיר עליו במפורש בעוד ההתקנות ממשיכות בכל זאת. למה הן ממשיכות — זה מחוץ למה שהנתונים כאן יכולים לענות. המספרים כאן סופרים התקנות, לא החלטות. אבל שום שינוי בממשק לא פותר את הקבוצה השנייה, שהיא גם הגדולה יותר.

פעילות מאגר והארטיפקט שפורסם יכולים להתפצל

השורה המרשימה ביותר במערך הנתונים שוברת את המסגרת לגמרי.

codelucas/newspaper — 15,126 כוכבים — הוא פעיל. ה-commit האחרון בענף ברירת המחדל שלו הוא מ-2026-07-21, מול תאריך מדידה של 2026-07-27, והוא נכתב בידי המתחזק. כל בדיקה ברמת המאגר עוברת.

החבילה שכולם מתקינים היא newspaper3k 0.2.8, שפורסמה ב-2018-09-28. זה 2,858 ימים של ותק, והיא מושכת 813,513 הורדות בחודש.

ענף ברירת המחדל עדכני, בעוד שהארטיפקט ב-PyPI לא שוחרר מאז 2018. זה מוכיח פער שחרור, לא למה החבילה לא שוחררה או אם צינור ה-build מקולקל. זה בדיוק סוג הסיכון שבדיקת תחזוקה ברמת מאגר בלבד הייתה מפספסת, כי הארטיפקט מהרישום הוא מה שבדרך כלל רץ אחרי pip install newspaper3k.

ברגע שמסתכלים על חבילות במקום על מאגרים, התבנית נמצאת בכל מקום. מבין 17 החבילות שהשיוך שלהן למאגר אומת, 16 שוחררו לאחרונה לפני יותר משנה, ו-16 אלה אחראיות לכ-2.28 מיליון התקנות בחודש מתוך 2.30 מיליון בסך הכול:

PackageInstalls/monthLast publishedPackage age (days)
newspaper3k813,5132018-09-282,858
tls-client790,3052024-02-02905
simhash317,6152022-03-031,606
microdata-node204,0252020-05-112,267
@modelcontextprotocol/server-puppeteer127,2322025-05-12440
extract-thinker10,9272025-06-09412
SetSimilaritySearch7,9842022-10-111,384
frontera4,7092019-04-052,669
zerox3,3032025-05-20432
scrapydweb1,1632025-02-16525
lavague6062024-08-05720
splash3332020-06-162,231
dragnet2132019-04-162,658
@builder.io/gpt-crawler1372025-01-23549
lmnr-index1202025-06-05416
simhash-py1132017-03-223,413

tls-client ראוי לשורה משלו: 790,305 התקנות בחודש ממאגר קפוא כבר 905 ימים, בקטגוריה שבה להישאר מעודכן זו כל העבודה. התנהגות TLS של דפדפנים משתנה; ספרייה שהפסיקה לעקוב אחרי זה בתחילת 2024 רצה על הנחות של תחילת 2024.

שתי הסתייגויות לגבי הטבלה הזאת. ספירות הורדה מרישום כוללות ריצות CI ומראות, ואינן מנרמלות כפילויות, כך שהן מודדות נפח התקנה, לא בני אדם. וחלונות המדידה אינם חולקים תאריך סיום זהה — של npm קרוב ל-2026-07-24, ושל pypistats יחסיים לזמן המשיכה — לכן הסכום הוא של חודשים שמעט הוזזו, ויש לקרוא אותו כ-"בערך 2.28 מיליון", לא עד הספרה האחרונה.

התנגשות השמות שכדאי להכיר

internetarchive/wayback הוא OpenWayback הישן ב-Java, קפוא כבר 1,916 ימים. wayback ב-PyPI הוא פרויקט אחר לגמרי — edgi-govdata-archiving/wayback — והוא בריא, לאחר ששחרר 0.5.1 ב-2026-06-19, חמישה שבועות לפני מועד המדידה. אותו שם, מצב הפוך, בלי קשר ביניהם. זה היה אחד מששת השיוכים שנדחו, וזה גם זה שסביר ביותר להכשיל משתמש אמיתי: חיפוש השם מביא את שניהם, ושום דבר באף אחד מהדפים לא אומר איזה מהם מצאת.

בארכיון, מסומן כ-deprecated, ועדיין מותקן 127,232 פעם בחודש

שישה מאגרים בדגימה מסומנים archived: true, ו-GitHub מציג זאת כבאנר ברוחב מלא. הקריאה הראשונה שלי הייתה שזה מוכיח שאנשים מתעלמים מאזהרות רועשות. המטמון אומר שהסיפור גרוע יותר מזה.

הפניה רשמית: npm download-count API documentation.

הפניה רשמית: npm's deprecation documentation.

@modelcontextprotocol/server-puppeteer מושך 127,232 התקנות בחודש מתוך modelcontextprotocol/servers-archived. אבל שדה ה-repository שלו ב-npm הוא null — אין קישור מדף החבילה חזרה למאגר, ולכן הבאנר הוא לא משהו שמתקין היה יכול פשוט לדלג עליו. לרוב האנשים שמורידים את החבילה הזו לא הייתה בכלל דרך אליה.

מה ש-npm כן מפרסם הוא ה-deprecation. הגרסה האחרונה של החבילה נושאת deprecated: "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info." — והטקסט הזה מודפס למסוף בזמן ההתקנה. כלומר, האזהרה נמסרת במקום שבו המשתמש באמת נמצא, ובכל זאת 127,232 התקנות בחודש ממשיכות. זו מסקנה חזקה יותר מהבאנר, והיא מצביעה לכיוון אחר: האות לא חסר, אלא מגיע בתוך ים של פלט התקנה שאיש אינו מוכרח לקרוא.

browserbase/mcp-server-browserbase מראה איך נראית סגירה נקייה: ה-commit האחרון בענף ברירת המחדל שלו, ב-2026-07-20, הוא ממש "Mark repository as archived and unmaintained (#198)". המתחזקים הכריזו, תיארכו וסימנו זאת ב-API. אבל 20,389 ההתקנות שלו ראויות לקריאה זהירה — חלון npm רץ מ-2026-06-25 עד 2026-07-24, כך ש-26 מתוך 30 הימים האלה קדמו ל-commit של הארכיון. כלומר, רוב המספר הוא ביקוש שלפני ההכרזה, לא מרד בה. מה קורה אחר כך באמת לא ידוע מהצילום הזה, והייתי רוצה קריאה נוספת חודש אחרי לפני שאקבע מסקנה.

57 כוכבים, 204,025 התקנות בחודש

ל-Janpot/microdata-node יש 57 כוכבים והוא מושך 204,025 הורדות בחודש מגרסה שפורסמה ב-2020-05-11.

עם 57 כוכבים, ל-microdata-node יש נראות מאגר נמוכה בהרבה מהיקף הפעילות ברישום. יחס התקנה-לכוכב של 3,579 ל-1 תואם שימוש עקיף, חזרות CI, מראות, או צריכה ישירה על-ידי מכונות. הבדיקה הזאת לא משכה גרפי תלות, ולכן לא יכולה לבחור בין ההסברים האלה.

השורה הזאת היא קריאה למיפוי חשיפה עקיפה, אבל הוכחת שימוש טרנזיטיבי דורשת ראיות של reverse-dependency או lockfile שהבדיקה הזאת לא אספה.

מיושן זה לא אותו דבר כמו שבור

בדיקה כנה חייבת לומר זאת: שום דבר כאן לא מודד אם משהו שבור. הוא מודד אם יש מישהו בבית.

חלק מהדברים האלה פשוט הושלמו. SetSimilaritySearch מממש אלגוריתמים של set-similarity; אלה לא נרקבים. simhash הוא מאמר מ-2007. אלגוריתם חילוץ התוכן של boilerpipe מתנהג ב-2026 בדיוק כמו ב-2015 — בלי קשר לדיוק שלו מול דפים מודרניים, הקוד לא זז מתחת לרגליים שלך.

מה שנרקב הוא כל דבר שבקצה השני שלו יש יעד משתנה:

  • אוטומציה של דפדפן — כל גרסת Chrome יכולה לשבור אותה.
  • התנהגות של HTTP client שמחקה דפדפנים אמיתיים — דפדפנים משתנים, וספרייה קפואה מפסיקה להתאים; tls-client יושב כאן.
  • Parser-ים ייעודיים לאתרים וכללי חילוץ לכל אתר — כל עיצוב מחדש של אתר הוא באג.
  • כל דבר שעוטף API של צד שלישי — הספק משנה את הסכימה ואתה מגלה זאת בפרודקשן.
  • כל דבר שעוטף LLM — דה-פריקציות של מודלים קורות מהר יותר מכל זה.

אז "1,606 ימים מיושן" הוא שריפה של חמש אזעקות בקטגוריה אחת, וכמעט לא רלוונטי בקטגוריה אחרת, כמו כלי hashing. כאן לא נבדקה שבירות, ואין כאן טענה עליה; מיון התלויות שלך לפי הקטגוריה שאליה הן שייכות לא עולה כלום ועוזר לך יותר מהמספר של ה-staleness לבדו.

ארבע הבדיקות שבאמת עונות על השאלה

System diagram: The four checks that actually answer the question

אף אחת מהן אינה כותרת המאגר.

#CheckWhere to read itWhat it catches
1The last commit on the default branchGET /repos/{owner}/{repo}/commits?sha={default_branch}&per_page=1The number that isn't shown to you.
2The last time the artifact shippedpypi.org/pypi/{pkg}/json or registry.npmjs.org/{pkg} → newest version and its upload dateThis is what catches newspaper3k, and check 1 never will. While you're there, read npm's deprecated field, which is how @modelcontextprotocol/server-puppeteer announces itself.
3The archived flagOne field in the repo response, unambiguous and freeNote that it only helps if you reached the repo at all, which repository: null packages don't let you do.
4The gap between 1 and 2— (derived from the two above)A repo with fresh commits and a three-year-old release is a different failure from one that's simply cold: it means the maintainer is present but not shipping. That's a decision to make with your eyes open, not a red flag on its own. The same logic applies in reverse to crawlab: check whether work moved to a non-default branch before concluding anything.

הריצו את בדיקות 1, 2 ו-3 כטריאז' מהיר. אחר כך הסלימו כשמטא-דאטה של המאגר חסר, שיוך החבילה עמום, הפעילות עברה לענף שאינו ברירת המחדל, או שהארטיפקט ברישום מתפצל מהמאגר. מגבלות קצב של GitHub ללא הזדהות והשהיה ברישומים הופכות הבטחה של שנייה אחת לבלתי מתאימה.

אם בדיקה מעלה משהו קפוא בקטגוריה שנעה, החלופות המתוחזקות במרחב הזה מתועדות בבדיקות שלנו: Trafilatura עבור חילוץ התוכן ש-dragnet ו-boilerpipe עשו פעם, Scrapy או Crawlee עבור מסגרות crawling, Crawl4AI ו-Firecrawl עבור חילוץ מכוון-LLM, ו-Scrapling כשחוסן הוא מה שחשוב. עמוד-העמוד שלנו על scraper בקוד פתוח עוקב אחרי המערך הרחב יותר. אלו סקירות ממקור ראשון; הריצו את ארבע הבדיקות בעצמכם לפני שאתם סומכים על כל המלצה, כולל שלנו.

מגבלות הנתונים האלה

  • בחירת הדגימה. נבחרה ידנית בגלל חשד לנטישה. אי אפשר לגזור ממנה שיעורי אקוסיסטם.
  • אין בדיקות שבירות. אף אחד מ-35 הכלים לא הורץ מול אתר חי. Staleness הוא אות תחזוקה, לא פסק דין תפקודי.
  • ספירות הורדה כוללות מכונות. CI, מראות, בלי דה-דופליקציה, ובחלונות שאין להם אותו תאריך סיום. נפח התקנה, לא משתמשים, ולא החלטות.
  • שבע סיבות לא ידועות נשארות לא ידועות. פיד הפעילות לא החזיר דבר, ולגבי חמישה מתוך השבעה retention לא מסביר זאת. עדיף להשאיר תא ריק מאשר למלא אותו בניחוש פופולרי.
  • staleness_days משתמש בתאריכי committer. היסטוריה שכתובה מחדש או מתוארכת לאחור תעוות אותו. לא זוהה דבר כזה, אבל זה לא זהה לכך שאין.
  • תאריך as-of אחד. 2026-07-27. כמה מהמאגרים האלה כבר זזו מאז שתקראו זאת — newspaper במיוחד מתחייב בקצב קבוע. הריצו מחדש את ארבע הבדיקות; אל תצטטו את התאריכים שלי.

איפה שירות מנוהל משנה את התמונה

כל בדיקה כאן קיימת כי עם ספרייה שמריצים בעצמכם, אתם הבעלים של ה-staleness. אם HTTP client קפוא מפסיק להתנהג כמו דפדפן עדכני, זה האירוע שלכם — באיזו שעה שזה יופיע.

הערת מחבר: Thunderbit הוא מוצר scraping מנוהל שלנו. שירות מנוהל מעביר חלק מאחריות התחזוקה לספק, אבל כיסוי, זמן תגובה, תלות בספק והמשכיותו נכנסים כולם למודל הסיכון. Thunderbit לא נבדק בביקורת הזו על מאגרים.

החלפה הכנה היא לוותר על היכולת לקרוא את הקוד, לנעול גרסה, ולתקן לבד בשתיים בלילה. לצוות שכבר מתחזק scrapers, המסלול בקוד פתוח הוא לעיתים קרובות הבחירה הנכונה — ארבע הבדיקות הן הדרך להפוך זאת להחלטה ולא להנחה.

נסה את Thunderbit לחילוץ נתוני ווב

הגרסה הקצרה

בניתי רשימה כדי להוכיח ש-GitHub מסתיר נטישה. האשליה אמיתית ב-14 מתוך 35 מאגרים, ובמקרה אחד היא דרמטית במיוחד: sjdirect/abot מציג push מהשבוע שעבר מול ענף ראשי שקפא מאז 2021 — פער של 1,802 ימים.

אבל המנגנון צר יותר מהסיפור. תשעה מאגרים עוברים את כל התנאים שהטענה דורשת, ורק שניים מתוך התשעה — splash ו-geziyor — כוללים ראיה חיובית לכך שבוטים אכן ניפחו את ה-pushed_at; היתר עוברים בגלל היעדר ראיות. בשני מאגרים מסומנים מדובר בבני אדם שניסו ונכשלו להחיות פרויקט. באחד, crawlab, יש 12,250 כוכבים והפיתוח פשוט עבר ל-develop. בשבעה, פיד הפעילות חזר ריק ושמירת ההיסטוריה לא מסבירה חמישה מהם, ולכן הסיבה אינה מוכחת אלא משוערת. וב-21 מתוך 35 המאגרים, GitHub דיווח על ה-staleness במדויק.

המקרה הגרוע ביותר במערך הנתונים עובר כל בדיקה ברמת המאגר. codelucas/newspaper עבר commit ב-2026-07-21; newspaper3k, שפורסם לאחרונה ב-2018-09-28, יצא 813,513 פעמים באותו חודש. לאורך המדגם, 16 חבילות שהגרסה האחרונה שלהן ישנה משנה אחראיות לכ-2.28 מיליון התקנות בחודש.

בדקו קודם את תאריך ה-commit בענף ברירת המחדל, את תאריך השחרור/העלאה ברישום, את דגל archived, ואת שדה ה-deprecated ב-npm. אחר כך פתרו את שיוך החבילה למאגר, ובדקו פיתוח בענפים שאינם ברירת המחדל לפני שמסיקים מסקנה.

נסה את Thunderbit לחילוץ נתוני ווב Get Started Free

שאלות נפוצות

מה זה pushed_at ולמה הוא לא אומר "עודכן לאחרונה"? pushed_at הוא שדה ה-API של GitHub שמזין את חותמת הזמן של הפעילות בדף המאגר, והוא מתרענן כשיש push לכל ענף שהוא. ה-commit האחרון בענף ברירת המחדל הוא אות תחזוקה אחד של המאגר, בעוד שמנהלי חבילות בדרך כלל מתקינים ארטיפקטים מהרישום או גרסאות מודול שנפתרו. בבדיקה הזו, ב-14 מתוך 35 המאגרים שני התאריכים של GitHub היו שונים ביותר מ-180 יום.

האם זה תמיד dependabot שמנפח את החותמת הזו? לא, וזו התבררה כחוליה החלשה ביותר בסיפור העממי. אם סופרים רק אירועים שהתרחשו אחרי ה-commit האחרון בענף ברירת המחדל, בוטים אושרו ב-3 מתוך 14 המאגרים המסומנים (splash 4 מתוך 4, geziyor 5 מתוך 5, any23 16 מתוך 16). עבור 2 זה פשוט שגוי: הפער של dragnet נובע מאדם שדחף פורט לא ממוזג ל-Python 3.10. עוד שניים הם מקרים מעורבים, כולל crawlab, שבו 24 pushes אנושיים עברו ל-develop ול-test בזמן ש-main עמד מלכת. וב-7 פיד הפעילות לא החזיר דבר, כך שהסיבה לא הוכחה — שמירת היסטוריה מסבירה רק שניים מתוך השבעה האלה.

האם מאגר מיושן אומר שהכלי שבור? לא על סמך הראיות כאן — שום דבר לא הורץ מול אתר חי. Staleness משנה ביחס לקצב שבו היעד זז: אוטומציית דפדפן, HTTP clients שמחקים התנהגות דפדפן, parsers ייעודיים לאתרים ועוטפי API/LLM מזדקנים מהר, בעוד ספריות אלגוריתמיות כמו SetSimilaritySearch או simhash יכולות להיות בנות שנים ולהיות תקינות לחלוטין. tls-client הוא המקרה החד ביותר בדגימה, עם 790,305 התקנות בחודש ממאגר קפוא כבר 905 ימים.

איך יכול להיות שמאגר פעיל אבל החבילה עצמה מתה? זה codelucas/newspaper, וזה הדבר המשמעותי ביותר שמצאתי בבדיקה. הענף הראשי שלו עבר commit ב-2026-07-21, ימים ספורים לפני תאריך המדידה, אבל newspaper3k ב-PyPI שוחררה לאחרונה כ-0.2.8 ב-2018-09-28 — 2,858 ימים — ועדיין מושכת 813,513 הורדות בחודש. בדיקות ברמת המאגר כולן עוברות; הארטיפקט שאתם מתקינים הוא בן שמונה שנים. תמיד בדקו את תאריך הפרסום האחרון ברישום בנפרד מהלוג של ה-commit.

האם מאגרים בארכיון פותרים את זה? GitHub הרי מציג באנר. לא באופן אמין, ו-@modelcontextprotocol/server-puppeteer מראה למה. שדה ה-repository שלו ב-npm הוא null, ולכן אין קישור מהחבילה למאגר בארכיון ואין באנר שאפשר לדלג עליו. מה ש-npm כן מציג הוא מחרוזת ה-deprecated של החבילה — "Package no longer supported" — שמודפסת בזמן ההתקנה, ובכל זאת 127,232 התקנות בחודש עוברות דרכה. browserbase/mcp-server-browserbase הכריז על הסגירה כראוי ב-commit האחרון שלו; 20,389 ההתקנות שלו הן ברובן לפני אותו commit, ולכן הן כמעט לא אומרות כלום לכאן או לכאן.

איך בודקים מהר את התלויות שלי? התחילו מתאריך ה-commit בענף ברירת המחדל, מתאריך גרסה/העלאה ברישום, משדה ה-deprecation ב-npm, ומדגל הארכיון של המאגר. אחר כך ודאו את שיוך החבילה למאגר, בדקו ענפים שאינם ברירת המחדל כשיש סטייה בפעילות, והשתמשו בגרפי תלויות או lockfiles לפני שאתם קובעים שהחשיפה היא טרנזיטיבית. התנגשויות שמות, כמו הפרויקטים הלא קשורים של Java ו-PyPI בשם wayback, הופכות את ההסלמה הזאת להכרחית.

Ke
Ke
CTO ב-Thunderbit | מדען נתונים בכיר ומומחה ב-ML עם כמעט עשור של ניסיון בלמידת מכונה ובמדע הנתונים, קה שן הוא בוגר אוניברסיטת קולומביה ולשעבר מדען נתונים בכיר ב-Walmart Labs. עם מומחיות עמוקה ומוכרת בקרב עמיתים ב-Python, R, Java וסטטיסטיקה, הוא משתף תובנות מוכחות-בקרב על המעבר מאלגוריתמי AI מורכבים מתיאוריה לארכיטקטורה ברמת production.
תוכן עניינים
Thunderbit · סוכן נתוני אינטרנט מבוסס AI

חלץ נתונים מכל דף בתוך קליק אחד

למעלה מ-250,000 משתמשים סומכים עליו
יש תוכנית חינמית
מדף אינטרנט לגיליון נתונים
תארו מה אתם צריכים — סוכן ה-AI של Thunderbit מחלץ את זה ומייצא ל-Excel, Google Sheets, Airtable או Notion. חינמי להתחלה.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week