HtmlAgilityPack – The best way to parse HTML

HtmlAgilityPack – The best way to parse HTML

בקושי עובר שבוע בלי שמישהו שואל שאלה בפורומי ASP.NET על ניתוח HTML למטרה זו או אחרת. בעיקר, השאלות מנוסחות במונחים של 'מציאת ערכים "או דומה,
מה שגרם תגובות מהקהילה שממליצות שימוש ב REGEX, בטיפול HTML כמחרוזת של טקסט ללא מבנה או כללים.
למעשה, HTML הוא פורמט מסמך מובנה עם סט של כללים מוגדרים בבירור, מה שאומר שזה יכול להיות מנותח בקלות בהינתן הכלי הנכון.
הכלי האהוב שלי עבור ניתוח HTML הוא HtmlAgilityPack.

HtmlAgilityPack  בסביבה כבר זמן מה, והוא זמין באמצעות Nuget. ניתן להתקין אותו באמצעות הפקודה

HAP מקבלת HTML כמחרוזת, קובץ, Stream או אובייקט TextReader. קוד ה- HTML הוא נטען לתוך אובייקט HtmlDocument בשיטת טעינה עבור Stream, קבצים וכן TextReader,
ושיטת LoadHtml עבור HTML  כמחרוזת. שתי השיטות הנפוצות ביותר הן אלה לטעון קובץ או מחרוזת:

לאחר טעינת ה HTML לצורך ניתוחו, ניתן לגשת אליו באמצעות אובייקט DocumentNodes של HtmlDocument שמחזירה את אלמנט השורש.
משם ניתן להשתמש ב LINQ או XPATH  על מנת "לתשאל" את המסמך או ליתר דיוק לגשת לאוסף ה HtmlNode שמוחזר על ידי שימוש בפונקציה Descendants.

הקוד הנ"ל יחזיר את המספר הכולל של אובייקטי HtmlNode (או רכיבי HTML) נמצאו במסמך. ניתן לסנן אותם במספר דרכים. לדוגמה, ניתן להוסיף שם תגית לפונקציית Descendants
ובעצם לסנן את השאילתה לפי תגית ה HTML. בקטע הקוד הבא נוכל לראות כיצד נסנן ונחזיר את כל תגיות ה anchor (עוגן) ורשימות לא סדורות במסמך:

תוכל לחדד את החיפוש על-ידי ציון אלמנטים שיש להם ערך מאפיין מסוים. דוגמה זו מחפשת את כל האלמנטים עם class של "-common-link":

איתור מידע ספציפי במסמך

אחד השימושים של HAP הוא לאיתור חלקים ספציפיים של תוכן במסמך HMTL. הדוגמה הבאה תמחיש איך להשיג תוכן ספציפי.
הצעד הראשון הוא לבדוק את ה- HTML הרלוונטי. כללתי רק קטע קטן המכיל את התוכן שברצוני לאתר (שורה 10) והדגשתי אותו:

התוכן אותו אני רוצה למקד ממוקם באלמנט p ללא תיוג מיוחד, כגון id או class attribute.במסמך ישנם מספר אלמנטים מסוג P, לכן מיקוד כולם לא יהיה מועיל. האסטרטגיה הטובה ביותר היא למקד אלמנט בודד לזיהוי בקלות, ולאחר מכן לנווט משם. ישנם כמה מועמדים ברורים למדי: div עם class של "post-rating" ועוד אחד בעל class של "module-profile-recognition". אם הייתי יוצר כלי לנתח את אותו הדף באופן קבוע, הייתי נמנע בדרך כלל מלמקד רכיבים על ידי שימוש ב CLASS, למרות היתכנות כי יופיעו רק פעם אחת בדף (כפי שקורה לשני יעדים פוטנציאליים במקרה זה), בעתיד עלולים להיות יותר מאחד.

ואחרי שהבהרנו את הנושא, אציג קוד המשתמש באלמנט  "module-profile-recognition":

כעת, אחרי שחילצנו את הטקסט מהאלמנט הרלוונתי (במקרה שלנו הפסקה), ניתן לחלץ את המספר עצמו עלי ידי שימוש ב Regex:

לסיכום:

זוהי הקדמה קצרה על HtmlAgiltyPack שהוא הכלי המומלץ עבור ניתוח HTML.
הוא מספק Linq to object API אשר מפשט את העבודה עם הספריה והופך אותה לקלה. אם אתה צריך לנתח או לתפעל HTML, זהו הכלי היחיד שאתה צריך.

Be the first to comment

Leave a Reply

כתובת האימייל שלך לא תפורסם


*