עיר אדומה? עיר ירוקה?

כולם מדברים רק על הערים האדומות - וזה מובן. 

אדום זה סכנה,

זה מפחיד,

זה סגר,

זה קורונה.

 

אבל אולי דווקא אתם הטיפוסים שמעדיפים לשמוע שהעיר שלכם ירוקה? או לפחות לחפש איזו עיר ירוקה לברוח אליה?

 

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

כתובת האתר היא:

https://www.gov.il/he

/Departments/DynamicCollectors/cities-ramzor

 

אבל אותנו יעניין ה API שמאחוריו.

 

עכשיו מסיבה שאני לא לגמרי מבין שירותי ממשלה שכבר טורחים ומפתחים API לא ממש להוטים לספר עליו.

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

https://www.gov.il/he/api/DataGovProxy/GetDGResults

שכבר החזירה לי את הנתונים בתוך JSON מסודר.

 

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

ולגלות את רשימת כל הערים הירוקות.

 

 

סקריפט 1 - שמירת נתוני הערים

 

בגלל שאין המון מידע אפשר להשתמש בספריה requests ולרוץ בלולאה פשוטה כדי למשוך את כולו.

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

 

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

את סך כל התוצאות מצאתי בחיפוש באתר הרגיל שלהם.

 

זה הקוד במלואו:

import requests
import json
all_data = []
s = requests.Session()
for i in range(0, 1236, 10):
    headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0',
            'Accept': 'application/json',
            'Accept-Language': 'en-US',
            'Referer': 'https://www.gov.il/he/Departments/DynamicCollectors/cities-ramzor?skip=0',
            'Content-Type': 'application/json;charset=utf8',
            'Origin': 'https://www.gov.il',
            'Pragma': 'no-cache',
            'Cache-Control': 'no-cache',
            }

    data = json.dumps({
        "DynamicTemplateID": "2dd7aea4-6f64-4eca-8465-98ee82fadd45",
        "QueryFilters": {"skip":{"Query":"0"}},
        "From": f"{i}"
        })


    url = 'https://www.gov.il/he/api/DataGovProxy/GetDGResults'
    r = s.post(url, headers=headers,data=data)
    batch = json.loads(r.text)
    all_data.extend(batch['Results'])
with open('data.json', 'w') as fp:
    json.dump(all_data, fp)

 

 

שימו לב שהוספתי לכתובת גם HTTP Headers.

 

לקחתי את הכותרות שהגיעו מהדפדפן כמו שהן.

אני חושב שחלק מהן מיותרות אבל לא התאמצתי לצמצם.

הסקריפט יוצר קובץ JSON בשם data.json שכולל את כל דירוגי הערים והצבעים שלהן.

 

כך נראית ההתחלה של הקובץ:

 

 

[
  {
    "Data": {
      "city_desc": "כפר קאסם",
      "score": "10.0",
      "link_city": "<b><u><a href=\"https://go.gov.il/red-city\">הנ
חיות והגבלות לישוב >> </a></b></u>",

      "Municipality_calc_desc": "כפר קאסם",
      "colour_Calc": "אדום",
      "citydesc": "ללא",
      "city_color": "<img src=\"https://www.gov.il/BlobFolder/generalpage/city-colors/he/Misc_red-city.png\">",
      "totalresults": "1236"
    },

    "Description": null,
    "UrlName": null
  },

  {
    "Data": {
      "city_desc": "לקיה",
      "score": "10.0",
      "link_city": "<b><u><a href=\"https://go.gov.il/red-city\">הנ
חיות והגבלות לישוב >> </a></b></u>",

      "Municipality_calc_desc": "לקיה",
      "colour_Calc": "אדום",
      "citydesc": "ללא",
      "city_color": "<img src=\"https://www.gov.il/BlobFolder/generalpage/city-colors/he/Misc_red-city.png\">",
      "totalresults": "1236"
    },

    "Description": null,
    "UrlName": null
  },
...
]


 

 

סקריפט 2 - קריאת הנתונים ל Data Frame

 

כשיש לנו נתונים טבלאיים הכי קל לפענח אותם באמצעות Pandas.

הקוד הבא יוצר Data Frame מתוך הנתונים:

 

import pandas as pd
import json
raw_data = json.load(open('data.json'))
raw_data = list(map(lambda entry: entry["Data"], raw_data))
data = pd.DataFrame(raw_data)
data.score = data.score.astype('float')
data.colour_Calc = data.colour_Calc.astype('category')




הקוד טוען את קובץ ה JSON, מושך מכל פריט מידע רק את שדה Data שלו (כי כל המידע שמור בתוך שדה זה) ויוצר Data Frame ממערך האוביקטים שהתקבל.

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

 

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

 

with pd.option_context('display.max_rows', None, 'display.max_columns', None):

        print(data[data.colour_Calc == 'ירוק'].city_desc)

www.tocode.co.il