Created
October 8, 2023 22:03
-
-
Save airscholar/3fb7127d4e25dbcb582274567083ac85 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import sys | |
| from datetime import datetime | |
| from airflow import DAG | |
| from airflow.operators.python import PythonOperator | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from pipelines.wikipedia_pipeline import extract_wikipedia_data, transform_wikipedia_data, write_wikipedia_data | |
| dag = DAG( | |
| dag_id='wikipedia_flow', | |
| default_args={ | |
| "owner": "Yusuf Ganiyu", | |
| "start_date": datetime(2023, 10, 1), | |
| }, | |
| schedule_interval=None, | |
| catchup=False | |
| ) | |
| extract_data_from_wikipedia = PythonOperator( | |
| task_id="extract_data_from_wikipedia", | |
| python_callable=extract_wikipedia_data, | |
| provide_context=True, | |
| op_kwargs={"url": "https://en.wikipedia.org/wiki/List_of_association_football_stadiums_by_capacity"}, | |
| dag=dag | |
| ) | |
| transform_wikipedia_data = PythonOperator( | |
| task_id='transform_wikipedia_data', | |
| provide_context=True, | |
| python_callable=transform_wikipedia_data, | |
| dag=dag | |
| ) | |
| write_wikipedia_data = PythonOperator( | |
| task_id='write_wikipedia_data', | |
| provide_context=True, | |
| python_callable=write_wikipedia_data, | |
| dag=dag | |
| ) | |
| extract_data_from_wikipedia >> transform_wikipedia_data >> write_wikipedia_data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| import pandas as pd | |
| from geopy import Nominatim | |
| NO_IMAGE = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/No-image-available.png/480px-No-image-available.png' | |
| def get_wikipedia_page(url): | |
| import requests | |
| print("Getting wikipedia page...", url) | |
| try: | |
| response = requests.get(url, timeout=10) | |
| response.raise_for_status() # check if the request is successful | |
| return response.text | |
| except requests.RequestException as e: | |
| print(f"An error occured: {e}") | |
| def get_wikipedia_data(html): | |
| from bs4 import BeautifulSoup | |
| soup = BeautifulSoup(html, 'html.parser') | |
| table = soup.find_all("table", {"class": "wikitable sortable"})[0] | |
| table_rows = table.find_all('tr') | |
| return table_rows | |
| def clean_text(text): | |
| text = str(text).strip() | |
| text = text.replace(' ', '') | |
| if text.find(' ♦'): | |
| text = text.split(' ♦')[0] | |
| if text.find('[') != -1: | |
| text = text.split('[')[0] | |
| if text.find(' (formerly)') != -1: | |
| text = text.split(' (formerly)')[0] | |
| return text.replace('\n', '') | |
| def extract_wikipedia_data(**kwargs): | |
| url = kwargs['url'] | |
| html = get_wikipedia_page(url) | |
| rows = get_wikipedia_data(html) | |
| data = [] | |
| for i in range(1, len(rows)): | |
| tds = rows[i].find_all('td') | |
| values = { | |
| 'rank': i, | |
| 'stadium': clean_text(tds[0].text), | |
| 'capacity': clean_text(tds[1].text).replace(',', '').replace('.', ''), | |
| 'region': clean_text(tds[2].text), | |
| 'country': clean_text(tds[3].text), | |
| 'city': clean_text(tds[4].text), | |
| 'images': 'https://' + tds[5].find('img').get('src').split("//")[1] if tds[5].find('img') else "NO_IMAGE", | |
| 'home_team': clean_text(tds[6].text), | |
| } | |
| data.append(values) | |
| json_rows = json.dumps(data) | |
| kwargs['ti'].xcom_push(key='rows', value=json_rows) | |
| return "OK" | |
| def get_lat_long(country, city): | |
| geolocator = Nominatim(user_agent='geoapiExercises') | |
| location = geolocator.geocode(f'{city}, {country}') | |
| if location: | |
| return location.latitude, location.longitude | |
| return None | |
| def transform_wikipedia_data(**kwargs): | |
| data = kwargs['ti'].xcom_pull(key='rows', task_ids='extract_data_from_wikipedia') | |
| data = json.loads(data) | |
| stadiums_df = pd.DataFrame(data) | |
| stadiums_df['location'] = stadiums_df.apply(lambda x: get_lat_long(x['country'], x['stadium']), axis=1) | |
| stadiums_df['images'] = stadiums_df['images'].apply(lambda x: x if x not in ['NO_IMAGE', '', None] else NO_IMAGE) | |
| stadiums_df['capacity'] = stadiums_df['capacity'].astype(int) | |
| # handle the duplicates | |
| duplicates = stadiums_df[stadiums_df.duplicated(['location'])] | |
| duplicates['location'] = duplicates.apply(lambda x: get_lat_long(x['country'], x['city']), axis=1) | |
| stadiums_df.update(duplicates) | |
| # push to xcom | |
| kwargs['ti'].xcom_push(key='rows', value=stadiums_df.to_json()) | |
| return "OK" | |
| def write_wikipedia_data(**kwargs): | |
| from datetime import datetime | |
| data = kwargs['ti'].xcom_pull(key='rows', task_ids='transform_wikipedia_data') | |
| data = json.loads(data) | |
| data = pd.DataFrame(data) | |
| file_name = ('stadium_cleaned_' + str(datetime.now().date()) | |
| + "_" + str(datetime.now().time()).replace(":", "_") + '.csv') | |
| # data.to_csv('data/' + file_name, index=False) | |
| data.to_csv('abfs://footballdataeng@footballdataeng.dfs.core.windows.net/data/' + file_name, | |
| storage_options={ | |
| 'account_key': 'pcrbWAsuPmzOH43lu1xang05pIs+g1Lys/bor0z59O38sVyWQNQ64AtEveMobZ2pIwCjqximReKY+ASt9dP/+A==' | |
| }, index=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment