עבודה עם selenium ספרייה לבדיקות תוכנה אוטומטיות
חבילת selenium של פייתון משמשת לביצוע בדיקות אוטומטיות של אתרים כי היא שולטת בדפדפן ומאפשרת לכוון את ההתנהגות שלו. לדוגמה, ניתן להשתמש ב-selenium כדי לבחון את ההתנהגות של טופס בתרחישים שונים ובדפדפנים שונים ואז להריץ את הסקריפט על אוטומט בכל יום באותה שעה כדי לוודא שהטופס תקין.
במדריך אשתמש ב- selenium כדי לאתר קישורים שבורים בדף. קישורים משמשים כדי לנווט בין דפים באינטרנט. קישור שבור נוצר כאשר הדף שאליו אמורים לנווט לא קיים או אינו מתפקד. במצב זה, המשתמש מקבל הודעת שגיאה, לדוגמה:
קישורים תקינים באתר נותנים חוויית משתמש טובה. לעומתם קישורים שבורים מרגיזים את המשתמשים ופוגעים בדירוג במנועי חיפוש והם גם צצים כל הזמן בגלל האופי הדינמי של הרשת. לכן, חשוב לבדוק את כל הקישורים באופן קבוע. הבעיה היא שאתר אינטרנט ממוצע תלוי במאות רבות של קישורים מה שהופך את הבדיקה הידנית של כולם ללא פרקטית. את הבעיה יכולים לפתור כלים אוטומטיים. במדריך אציג סקריפט פייתון המטפל בבעיה בעזרת חבילת selenium.
דפי האינטרנט מודיעים על מצבם באמצעות קוד סטטוס (status code). דפים תקינים מציגים סטטוס בטווח 200-299. דפים שהועתקו ממקומם במתכוון מציגים סטטוס בטווח 300-399. קישורים שבורים מחזירים תגובה בטווח הגבוה מ-399. לדוגמה, 404 - הדף לא נמצא או 500 - הדף קיים אבל שגיאת שרת מונעת את הצגתו.
הסקריפט
נתחיל מהצגת הסקריפט במלואו. בהמשך נסביר אותו.
הסקריפט:
- פותח את הדפדפן ומנווט לדף אינטרנט שצריך להגדיר את כתובתו
- ממצה מהדף את כל הקישורים שאותם הוא מזהה
- מריץ לולאה המכילה בדיקה לסטטוס התגובה של כל קישור
- מדפיס את הקישורים השבורים
- מדפיס סיכום של מספר הקישורים שנבדקו וכמה מהם שבורים
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
# browser options
options = webdriver.FirefoxOptions()
# 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")
# browser without GUI
# options.add_argument("-headless")
# the size of the browser that selenium opens
options.add_argument("start-maximized")
# call the driver
executable_path = './geckodriver'
service = Service(executable_path = executable_path, log_output = "standard")
driver = webdriver.Firefox(service=service, options=options)
# Open up the URL and navigate to the page
driver.get('https://whatever.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 צריך דרייבר שיפעיל את הדפדפן בהתאם לקוד שאנחנו כותבים. את הדרייבר ניתן להוריד מ GeckoDriver - WebDriver for FireFox וחשוב שהוא יתאים למערכת ההפעלה והדפדפן איתם אנו עובדים. אני עובד עם דפדפן פיירפוקס על מערכת הפעלה לינוקס.
אחרי הורדת הדרייבר והמיצוי שלו באמצעות zip צריך להעביר את קובץ ה-executable למקום שממנו פייתון יפעיל אותו. נכנס לתיקייה שמכילה את הקובץ ונעתיק אותו מתיקיית ההורדה למקומו הקבוע בתיקיית הפרויקט בתוכה אנו עובדים על הפרויקט הדורש Selenium:
$ sudo cp ~/Downloads/geckodriver ./geckodriver
הסבר על הסקריפט
נייבא את החבילות:
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
נגדיר את התנהגות הדפדפן בתוך האובייקט options:
# browser options
options = webdriver.FirefoxOptions()
# 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")
# browser without GUI
# options.add_argument("-headless")
# the size of the browser that selenium opens
options.add_argument("start-maximized")
ישנם הרבה פקודות שניתן להעביר לדפדפן כפי שניתן לקרוא ברשימה.
נפעיל את הדרייבר עם האופציות שהכנו לעיל ועם הנתיב לתוכנה:
# call the driver
executable_path = './geckodriver'
service = Service(executable_path = executable_path, log_output = "standard")
driver = webdriver.Firefox(service=service, options=options)
נפנה את הדפדפן לדף האינטרנט שאותו אנו רוצים לבדוק. זה המקום שלך להזין את ה-URL של הדף:
# Open up the URL and navigate to the page
driver.get('https://whatever.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.
לקריאת הדוקומנטציה של החבילה Selenium.
לכל המדריכים בסדרה ללימוד פייתון
אהבתם? לא אהבתם? דרגו!
0 הצבעות, ממוצע 0 מתוך 5 כוכבים
המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.
למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.
שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.
המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?
השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.