איתור קישורים שבורים בדף אינטרנט באמצעות פייתון ו-selenium

מחבר:
בתאריך:

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

בדיקות אוטומטיות עם selenium python

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

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

במדריך אשתמש ב- selenium כדי לאתר קישורים שבורים בדף. לקריאת הדוקומנטציה של החבילה.

בדיקות אוטומטיות עם selenium python

דפי האינטרנט מודיעים על מצבם באמצעות קוד סטטוס (status code). דפים תקינים מציגים סטטוס בטווח 200-299. דפים שהועתקו ממקומם במתכוון מציגים סטטוס בטווח 300-399. קישורים שבורים מחזירים תגובה בטווח הגבוה מ-399. לדוגמה, 404 - הדף לא נמצא או 500 - הדף קיים אבל שגיאת שרת מונעת את הצגתו.

 

הסקריפט

נתחיל מהצגת הסקריפט במלואו. בהמשך נסביר אותו.

הסקריפט:

  1. פותח את הדפדפן ומנווט לדף אינטרנט שצריך להגדיר את כתובתו
  2. ממצה מהדף את כל הקישורים שאותם הוא מזהה
  3. מריץ לולאה המכילה בדיקה לסטטוס התגובה של כל קישור
  4. מדפיס את הקישורים השבורים
  5. מדפיס סיכום של מספר הקישורים שנבדקו וכמה מהם שבורים
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
# browser options
options = webdriver.ChromeOptions()
# trust non https websites
options.add_argument('--ignore-certificate-errors')
# automated tests in the browser
options.add_argument("--test-type")
# set the browser mode
options.add_argument("--incognito")
# where is the binary
options.binary_location = "/usr/bin/geckodriver"
# the size of the browser that selenium opens
options.add_argument("start-maximized")
# to make the options list effective
driver = webdriver.Chrome(chrome_options=options)

# Open up the URL and navigate to the page
driver.get('https://XXX.com')

# wait before extracting
delay = 5 # seconds
# extract all the links from the page
elems = driver.find_elements_by_css_selector('a')

# filter out non http links
refs = []
for elem in elems:
  ref = elem.get_attribute('href')
  if ref.startswith('http'):
    refs.append(ref)
    
# find broken links
counter = 0
counterValid = 0
for ref in refs:
  try:
    # send request, count and report the broken links
    r = requests.head(ref)
    if r.status_code < 400:
      # print(str(ref), ' is not broken')
      counterValid = counterValid + 1
    else:
      print(str(ref) , ' error code: ' , str(r.status_code))
  except Exception:
    print(str(ref) , ' encountered an exception')
  finally:
    counter = counter + 1

# summary line
broken = counter - counterValid
print('Number of links tested: ' , str(counter) , ' Number of OKs: ' , str(counterValid) , ' Number of broken: ' , str(broken))

driver.close()

 

התקנת החבילה

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

$ pip3 install selenium
$ pip3 install requests

selenium היא חבילת קוד המשמשת לבדיקות אוטומטיות של דפי אינטרנט. נשתמש בה כדי לנווט באופן אוטומטי לכתובת אינטרנט, וכדי למצות את הקישורים מהדף.

requests היא החבילה העיקרית שבה משתמשים כדי לבצע קריאות requests (באינטרנט). נשתמש בה כדי לבחון את התגובה של הקישורים והאם הם שבורים.

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

אחרי הורדת הדרייבר והמיצוי שלו באמצעות zip צריך להעביר את קובץ ה-executable למקום שממנו פייתון יפעיל אותו. נכנס לתיקייה שמכילה את הקובץ ונעתיק אותו למקומו הקבוע:

$ sudo cp geckodriver /usr/bin/geckodriver

 

הסבר על הסקריפט

נייבא את החבילות:

import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

נגדיר את התנהגות הדפדפן בתוך האובייקט options:

# browser options
options = webdriver.ChromeOptions()
# trust non https websites
options.add_argument('--ignore-certificate-errors')
# automated tests in the browser
options.add_argument("--test-type")
# set the browser mode
options.add_argument("--incognito")
# where is the binary
options.binary_location = "/usr/bin/geckodriver"
# the size of the browser that selenium opens
options.add_argument("start-maximized")

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

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

#  call the driver
driver = webdriver.Chrome(chrome_options=options)

נפנה את הדפדפן לדף האינטרנט שאותו אנו רוצים לבדוק. זה המקום שלך להזין את ה-URL של הדף:

# Open up the URL and navigate to the page
driver.get('https://XXX.com')

נורה ל-selenium לחכות לפני שהוא קוצר את תוכן הדף:

# wait before extracting
delay = 5 # seconds

המתנה קצרה יכולה לסייע לנו להתמודד עם תוכן של דף שעולה ב-AJAX (יש מודולים יותר מתוחכמים של selenium לטיפול בבעיה) והוא גם חשוב כשסורקים כמות גדולה של דפים כדי שהאתר לא יחסום אותנו.

אנחנו רוצים למצות את רשימת הקישורים מהדף. את הקישורים נזהה כתגיות A של HTML:

# extract all the links from the page
elems = driver.find_elements_by_css_selector('a')

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

# filter out non http links
refs = []
for elem in elems:
  ref = elem.get_attribute('href')
  if ref.startswith('http'):
    refs.append(ref)

את רשימת הקישורים שמעניינים אותנו אספנו לתוך המשתנה refs.

השורות הבאות של הסקריפט מריצות לולאה על רשימת הקישורים ובודקת עבור כל קישור את קוד הסטטוס status code שהוא מחזיר. אם סטטוס הקוד נמוך מ-400 אז הקישור תקין והסקריפט מוסיף 1 למניין הקישורים התקינים. אם הקישור מחזיר סטטוס קוד הגבוה מ-399 זה מעיד על התכנות של קישור שבור. במקרה כזה, הקישור וקוד הסטטוס מודפסים למסך ונוסיף 1 למניין הקישורים השבורים.

# find broken links
counter = 0
counterValid = 0
for ref in refs:
  try:
    # send request, count and report the broken links
    r = requests.head(ref)
    if r.status_code < 400:
      # print(str(ref), ' is not broken')
      counterValid = counterValid + 1
    else:
      print(str(ref) , ' error code: ' , str(r.status_code))
  except Exception:
    print(str(ref) , ' encountered an exception')
  finally:
    counter = counter + 1
  • אני מריץ את הקוד בתוך בלוקים try...except כי כשעובדים עם משאב מרוחק שמקורו ברשת האינטרנט אין לדעת באילו תופעות נתקל.
  • בתוך בלוק ה finally נעדכן את מונה סך כל הקישורים כי הבלוק תמיד רץ בין אם הקוד נתקל בשגיאה או לא.
  • את סטטוס התגובה של הקישור נקבל באמצעות הפעלת החבילה requests:
r = requests.head(ref)

נבחן את קוד התגובה המאוחסן במשתנה r לעיל:

if r.status_code < 400:
  # print(str(ref), ' is not broken')
  counterValid = counterValid + 1
else:
  print(str(ref) , ' error code: ' , str(r.status_code))

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

# summary line
broken = counter - counterValid
print('Number of links tested: ' , str(counter) , ' Number of OKs: ' , str(counterValid) , ' Number of broken: ' , str(broken))

נסגור את ההתקשרות עם הדרייבר:

driver.close()

 

סיכום

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

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

הוסף תגובה חדשה

 

= 4 + 8