מדריך ל- Crawler4j

1. הקדמה

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

במדריך זה נלמד כיצד להשתמש ב- crawler4j כדי להקים ולהפעיל סורקי אינטרנט משלנו. crawler4j הוא פרויקט Java בעל קוד פתוח המאפשר לנו לעשות זאת בקלות.

2. התקנה

בואו נשתמש ב- Maven Central כדי למצוא את הגרסה העדכנית ביותר ולהביא את התלות של Maven:

 edu.uci.ics crawler4j 4.4.0 

3. יצירת סורקים

3.1. סורק HTML פשוט

נתחיל ביצירת סורק בסיסי שסורק את דפי ה- HTML עליו //baeldung.com.

בואו ניצור את הסורק שלנו באמצעות הרחבה WebCrawler בכיתת הסורקים שלנו והגדרת תבנית שלא תכלול סוגי קבצים מסוימים:

class public HtmlCrawler מרחיב את WebCrawler js

בכל כיתת סורקים, עלינו לעקוף וליישם שתי שיטות: צריך לבקר ו לְבַקֵר.

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

@Override בוליאני ציבורי shouldVisit (עמוד referringPage, WebURL url) {String urlString = url.getURL (). ToLowerCase (); חזור! EXCLUSIONS.matcher (urlString) .matches () && urlString.startsWith ("// www.baeldung.com/"); }

לאחר מכן נוכל לבצע את העיבוד שלנו עבור דפים שביקרו בהם לְבַקֵר שיטה:

@ עקוב על ביקור חלל ציבורי (עמוד) {מחרוזת url = page.getWebURL (). GetURL (); אם (page.getParseData () מופע של HtmlParseData) {HtmlParseData htmlParseData = (HtmlParseData) page.getParseData (); כותרת מחרוזת = htmlParseData.getTitle (); טקסט מחרוזת = htmlParseData.getText (); מחרוזת html = htmlParseData.getHtml (); הגדר קישורים = htmlParseData.getOutgoingUrls (); // לעשות משהו עם הנתונים שנאספו}}

לאחר שכתבנו את הסורק, עלינו להגדיר ולהפעיל אותו:

קובץ crawlStorage = קובץ חדש ("src / test / resources / crawler4j"); CrawlConfig config = חדש CrawlConfig (); config.setCrawlStorageFolder (crawlStorage.getAbsolutePath ()); מספר numCrawlers = 12; PageFetcher pageFetcher = PageFetcher חדש (config); RobotstxtConfig robotstxtConfig = RobotstxtConfig חדש (); RobotstxtServer robotstxtServer = RobotstxtServer חדש (robotstxtConfig, pageFetcher); בקר CrawlController = CrawlController חדש (config, pageFetcher, robotstxtServer); controller.addSeed ("// www.baeldung.com/"); CrawlController.WebCrawlerFactory מפעל = HtmlCrawler :: חדש; controller.start (מפעל, numCrawlers);

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

עלינו לציין זאת גם ה CrawlController.start () השיטה היא פעולת חסימה. כל קוד לאחר אותה שיחה יבוצע רק לאחר שהסורק סיים לרוץ.

3.2. ImageCrawler

כברירת מחדל, crawler4j אינו סורק נתונים בינאריים. בדוגמה הבאה זו, נפעיל את הפונקציונליות ואת לסרוק את כל ה- JPEG ב- Baeldung.

נתחיל בהגדרת ה- ImageCrawler שיעור עם קונסטרוקטור שלוקח ספריה לשמירת תמונות:

מחלקה ציבורית ImageCrawler מרחיב את WebCrawler {דפוס סטטי סופי פרטי EXCLUSIONS = Pattern.compile (". * (\. (css | js | xml | gif | png | mp3 | mp4 | zip | gz | pdf)) $"); דפוס סופי סטטי פרטי IMG_PATTERNS = Pattern.compile (". * (\. (jpg | jpeg)) $"); קובץ פרטי saveDir; ImageCrawler ציבורי (קובץ saveDir) {this.saveDir = saveDir; } // קוד נוסף}

לאחר מכן, בואו ליישם את צריך לבקר שיטה:

@Override בוליאני ציבורי shouldVisit (עמוד referringPage, WebURL url) {String urlString = url.getURL (). ToLowerCase (); אם (EXCLUSIONS.matcher (urlString) .matches ()) {return false; } אם (IMG_PATTERNS.matcher (urlString) .matches () || urlString.startsWith ("// www.baeldung.com/")) {return true; } להחזיר שקר; }

כעת, אנו מוכנים ליישם את לְבַקֵר שיטה:

@ עקוב על ביקור חלל ציבורי (עמוד) {מחרוזת url = page.getWebURL (). GetURL (); אם (IMG_PATTERNS.matcher (url) .matches () && page.getParseData () מופע של BinaryParseData) {סיומת מחרוזת = url.substring (url.lastIndexOf (".")); int contentLength = page.getContentData (). אורך; // כתוב את נתוני התוכן לקובץ בספריית השמירה}}

מריץ את שלנו ImageCrawler דומה להפעלת HttpCrawler, אך עלינו להגדיר אותו כך שיכלול תוכן בינארי:

CrawlConfig config = CrawlConfig חדש (); config.setIncludeBinaryContentInCrawling (נכון); // ... אותו דבר כמו לפני CrawlController.WebCrawlerFactory מפעל = () -> ImageCrawler חדש (saveDir); controller.start (מפעל, numCrawlers);

3.3. איסוף מידע

כעת, לאחר שבחנו כמה דוגמאות בסיסיות, בואו נרחיב את הדוגמאות שלנו HtmlCrawler לאסוף כמה נתונים סטטיסטיים בסיסיים במהלך הסריקה שלנו.

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

מחלקה ציבורית CrawlerStatistics {private int ProcessPageCount = 0; פרטי int totalLinksCount = 0; בטל ציבורי incrementProcessedPageCount () {processorPageCount ++; } increment public voidTotalLinksCount (int linksCount) {totalLinksCount + = linksCount; } // גטרים סטנדרטיים}

הבא, בואו לשנות את שלנו HtmlCrawler לקבל א CrawlerStatistics מופע באמצעות קונסטרוקטור:

סטטיסטיקה פרטית של CrawlerStatistics; HtmlCrawler ציבורי (סטטיסטיקות CrawlerStatistics) {this.stats = סטטיסטיקה; }

עם החדש שלנו CrawlerStatistics אובייקט, בואו לשנות את לְבַקֵר שיטה לאסוף את מה שאנחנו רוצים:

@ עקוב על ביקור חלל ציבורי (עמוד) {מחרוזת url = page.getWebURL (). GetURL (); stats.incrementProcessedPageCount (); אם (page.getParseData () מופע של HtmlParseData) {HtmlParseData htmlParseData = (HtmlParseData) page.getParseData (); כותרת מחרוזת = htmlParseData.getTitle (); טקסט מחרוזת = htmlParseData.getText (); מחרוזת html = htmlParseData.getHtml (); הגדר קישורים = htmlParseData.getOutgoingUrls (); stats.incrementTotalLinksCount (links.size ()); // לעשות משהו עם נתונים שנאספו}}

עכשיו, בואו נחזור לבקר שלנו ונספק את HtmlCrawler עם מופע של CrawlerStatistics:

סטטיסטיקה של CrawlerStatistics = CrawlerStatistics חדש (); CrawlController.WebCrawlerFactory מפעל = () -> HtmlCrawler חדש (סטטיסטיקה);

3.4. סורקים מרובים

בהסתמך על הדוגמאות הקודמות שלנו, בואו נסתכל כיצד אנו יכולים להריץ מספר סורקים מאותו בקר.

מומלץ כל סורק משתמש בספריית האחסון הזמנית שלואז עלינו ליצור תצורות נפרדות עבור כל אחת מהן נפעיל.

ה סריקת בקרים יכול לשתף סינגל RobotstxtServerאבל אחרת, בעצם אנו זקוקים לעותק של הכל.

עד כה השתמשנו ב CrawlController.start שיטה להפעלת הסורקים שלנו וציין שזו שיטת חסימה. כדי להפעיל מכפילים, נשתמש CrawlerControlller.startNonBlocking בשיתוף עם CrawlController.waitUntilFinish.

עכשיו בואו ניצור בקר להפעלה HtmlCrawler ו ImageCrawler במקביל:

קובץ crawlStorageBase = קובץ חדש ("src / test / resources / crawler4j"); CrawlConfig htmlConfig = CrawlConfig חדש (); CrawlConfig imageConfig = CrawlConfig חדש (); // הגדר תצורה של תיקיות אחסון ותצורות אחרות PageFetcher pageFetcherHtml = PageFetcher חדש (htmlConfig); PageFetcher pageFetcherImage = PageFetcher חדש (imageConfig); RobotstxtConfig robotstxtConfig = RobotstxtConfig חדש (); RobotstxtServer robotstxtServer = RobotstxtServer חדש (robotstxtConfig, pageFetcherHtml); CrawlController htmlController = CrawlController חדש (htmlConfig, pageFetcherHtml, robotstxtServer); CrawlController imageController = CrawlController חדש (imageConfig, pageFetcherImage, robotstxtServer); // הוסף כתובות אתרים של זרעים סטטיסטיקות CrawlerStatistics = CrawlerStatistics חדש (); CrawlController.WebCrawlerFactory htmlFactory = () -> HtmlCrawler חדש (סטטיסטיקות); קובץ saveDir = קובץ חדש ("src / test / resources / crawler4j"); CrawlController.WebCrawlerFactory imageFactory = () -> ImageCrawler חדש (saveDir); imageController.startNonBlocking (imageFactory, 7); htmlController.startNonBlocking (htmlFactory, 10); htmlController.waitUntilFinish (); imageController.waitUntilFinish ();

4. תצורה

כבר ראינו כמה ממה שאנחנו יכולים להגדיר. עכשיו, בואו נעבור על כמה הגדרות נפוצות אחרות.

ההגדרות מוחלות על ה- CrawlConfig למשל אנו מציינים בבקר שלנו.

4.1. הגבלת עומק הסריקה

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

crawlConfig.setMaxDepthOfCrawling (2);

כתובות אתרים של זרעים נחשבות לעומק 0, כך שעומק הסריקה של 2 יעבור שתי שכבות מעבר לכתובת האתר של הזרע.

4.2. מקסימום דפים לאחזור

דרך נוספת להגביל את מספר הדפים הסורקים שלנו יכסה היא להגדיר את מספר הדפים המרבי לסריקה:

crawlConfig.setMaxPagesToFetch (500);

4.3. מקסימום קישורים יוצאים

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

crawlConfig.setMaxOutgoingLinksToFollow (2000);

4.4. עיכוב נימוס

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

crawlConfig.setPolitenessDelay (300);

4.5. כלול תוכן בינארי

כבר השתמשנו באפשרות לכלול תוכן בינארי עם שלנו ImageCrawler:

crawlConfig.setIncludeBinaryContentInCrawling (נכון);

4.6. כלול HTTPS

כברירת מחדל, הסורקים יכללו דפי HTTPS, אך אנו יכולים לכבות את זה:

crawlConfig.setIncludeHttpsPages (false);

4.7. זחילה ניתנת לזיהוי

אם יש לנו סורק ארוך טווח ואנחנו רוצים שהוא יתחדש אוטומטית, נוכל להגדיר סריקה המתחדשת. הפעלתו עלולה לגרום לו לרוץ לאט יותר:

crawlConfig.setResumableCrawling (נכון);

4.8. מחרוזת סוכן משתמש

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

crawlConfig.setUserAgentString ("הדגמת baeldung (//github.com/yasserg/crawler4j/)");

רק כיסינו כאן כמה מהתצורות הבסיסיות. אנחנו יכולים להסתכל CrawConfig בכיתה אם אנו מעוניינים בכמה מאפשרויות התצורה המתקדמות או הלא ברורות יותר.

5. מסקנה

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

דוגמאות הקוד המלאות זמינות באתר GitHub.