• בלוג
  • בואו נדפיס את כל הכותרות מרוטר נט לשורת הפקודה

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

אני לא יודע אם בטעות או בכוונה אבל כשאחד הקוראים ניסה לקחת את דוגמת הקוד שפירסמתי כאן לפני כמה ימים ולהתאים אותה לרוטר כך שתדפיס את כל הכותרות משם במקום מ ynet הסיפור לא נגמר יפה. מסתבר שה HTML של רוטר נט לא התאים למבנה ש Beatiful Soup ציפו לו.

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

<!--</u>531268</u><--></u><span style='font-size:9.0pt;color:red'><b>16:29</b></span>&nbsp; <a target='news' HREF='http://rotter.net/forum/scoops1/531268.shtml'><span style='font-size:10.0pt;color:000099'></g>אחרי הספירה גדעון סער מקום רביעי</g></span></a><br>

שימו לב לתג ה g שמקיף את ההודעה על זכייתו של סער במקום הרביעי. בטעות או בכוונה לפני הטקסט מופיע שם תג סוגר. מבחינת Beautiful Soup ופרסרים רבים נוספים בשביל לסגור את ה g צריך לסגור קודם את ה a שמעליו ולכן הטקסט שאתם רואים בכלל לא נמצא בתוך אלמנט ה a.

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

import requests
from bs4 import BeautifulSoup
from lxml.html.soupparser import fromstring
from lxml import etree

url = 'http://rotter.net/'
r = requests.get(url)
r.encoding = 'iso8859-8'
root = fromstring(r.text)
headlines = [
        text for text in root.xpath('//a[@target="news"]/../text()')
        if text != '\n' and text != '\n\n' and text != '\xa0 '
]

for text in headlines:
    print(text)

בניגוד ל ynet, ברוטר ה Character Encoding לא מוגדר טוב ולכן צריך להגיד ל requests בצורה מפורשת שאנחנו רוצים עברית. פקודת ה xpath למציאת הטקסטים היתה:

root.xpath('//a[@target="news"]/../text()')

זה מאוד מזכיר CSS Selector מלבד סימן הנקודה-נקודה שמציין מעבר לאלמנט ההורה. בעברית זה יישמע משהו כמו - קח כל אלמנט a שיש לו מאפיין target עם ערך news, תמצא את ההורה של כל אחד מהם, ומההורה הזה קח את כל הטקסטים שנמצאים ישירות תחתיו. אלה בדיוק הטקסטים שיימצאו "ליד" אלמנטי ה a, בגלל שה g גרם להם לצאת מה a.

מעניין לציין שלדפדפנים אין את הבעיה הזאת ובתוך ה Developer Console של כרום אנחנו יכולים בכיף לכתוב:

$$('a[target="news"]')[0].textContent

כדי לקבל את הטקסט של האייטם הראשון.

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

https://www.tocode.co.il/workshops/64