Skip to content

Commit 31a1a4e

Browse files
committed
Переделано на everything
1 parent 3f8f39e commit 31a1a4e

8 files changed

Lines changed: 43 additions & 36 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ db: создается база данных и таблица если их е
1515
Pipeline: программа запускается скриптом разделенным на 5 основных модулей (db.py, extract.py, load.py, transform.py, main.py)
1616

1717
### Схема ETL
18-
top-headlines из NewsApi (extract) -> Филтр на наличие автора, заголовка, описания не меньше 20 символов, наличие url (transform) -> загрузка статей чей url отсутствует в базе данных (load)
18+
Everything из NewsApi (extract) -> Филтр на наличие автора, заголовка, описания не меньше 20 символов, наличие url (transform) -> загрузка статей чей url отсутствует в базе данных (load)
1919

2020
### Структура папок
2121
```text

config/config.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ class Settings:
3131
db_news: str = os.getenv("DB_NEWS","news_db")
3232

3333
KEY_API: str = os.getenv("NEWSAPI_KEY", "NO")
34-
NEWS_URL = "https://newsapi.org/v2/top-headlines"
34+
NEWS_URL = "https://newsapi.org/v2/everything"
3535

36-
COUNTRY = "US"
36+
langueage = "ru"
37+
sortBy = "publishedAt"
3738

3839
settings = Settings()
3940

main.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ def parse_args():
2424
required=True,
2525
help="Keyword for news search"
2626
)
27-
28-
parser.add_argument(
29-
"--category",
30-
required=True,
31-
help="Category for news search"
32-
)
3327
parser.add_argument(
3428
"--limit",
3529
type=positive_int,
@@ -48,23 +42,22 @@ def parse_args():
4842
def pipeline() -> None:
4943
args = parse_args()
5044
key_word = args.keyword
51-
category = args.category
5245
limit = args.limit
5346
page_size = args.page_size
5447
num_of_news = 0
5548
page = 1
5649
while num_of_news < limit:
5750
remaining = limit - num_of_news
58-
raw_file_name,raw_articles_count = make_extract(category, key_word, page, page_size)
51+
raw_file_name,raw_articles_count = make_extract(key_word, page, page_size)
5952
if raw_articles_count == 0:
6053
logger.warning("there is no more artical")
6154
break
62-
clean_file_name = transform_article(raw_file_name, category, key_word, page)
55+
clean_file_name = transform_article(raw_file_name, key_word, page)
6356
result_num_of_news = load_news(clean_file_name, max_rows=remaining)
6457

6558
num_of_news += result_num_of_news
6659
page += 1
67-
logger.info(f"{num_of_news} news on category {category} already aploaded")
60+
logger.info(f"{num_of_news} news on key word {key_word} already aploaded")
6861
return num_of_news
6962

7063
def main()-> None:

notebooks/01_eda.ipynb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,26 @@
1515
"import os\n",
1616
"from pathlib import Path \n",
1717
"import pandas as pd \n",
18-
"import mathplotlib.pyplot as plt \n",
19-
"3"
18+
"import mathplotlib.pyplot as plt \n"
19+
]
20+
},
21+
{
22+
"cell_type": "markdown",
23+
"id": "8f9db0d1",
24+
"metadata": {},
25+
"source": [
26+
"В чем поинт происходящего. Помимо очевидного сбора новостей, мне захотелось собрать некую статистику. \n",
27+
"Как много статей от общего числа не проходят фильтр?\n",
28+
"По каким критериям они не проходят?\n",
29+
"Что является первичной причиной отброса?\n",
30+
"Как часто по каждому ключевому слову попадаются одинаковые ссылки?\n",
31+
"и главный вопрос, кто такой E_nota?\n",
32+
"\n",
33+
"Что будет происходить у меня далее?\n",
34+
"Я буду считывать статистику из data/clean/stats скорее всего я буду после этого чистить папки data/clean и data/raw чтобы избегать использования лишней памяти. После чего я буду строить графики на тему:\n",
35+
"А что является чаще всего причиной отброса в целом?\n",
36+
"А что явяется чаще всего причиной по каждой теме?\n",
37+
"А какое ключивое слово имеет больше всего одинаковых ссылок?"
2038
]
2139
}
2240
],

src/db.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ def create_news_tables() -> None:
7474
query = """
7575
CREATE TABLE IF NOT EXISTS bad_news_bears (
7676
id BIGSERIAL PRIMARY KEY,
77-
country VARCHAR NOT NULL,
78-
category VARCHAR NOT NULL,
77+
language VARCHAR NOT NULL,
7978
key_word VARCHAR NOT NULL,
8079
author VARCHAR,
8180
title TEXT NOT NULL,

src/extract.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
logger = logging.getLogger(__name__)
1010
BASE_DIR = Path(__file__).resolve().parent.parent
1111

12-
def import_to_raw_json(data:dict[str, Any], category: str, key_word: str, page: int) -> str:
12+
def import_to_raw_json(data:dict[str, Any], key_word: str, page: int) -> str:
1313
raw_dir = BASE_DIR / "data" / "raw"
1414
raw_dir.mkdir(parents=True, exist_ok=True)
1515
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
16-
create_data = f"{timestamp}_{category}_{key_word}_page_{page}.json"
16+
create_data = f"{timestamp}_{key_word}_page_{page}.json"
1717
file_path = raw_dir / create_data
1818

1919
with open(file_path, "w", encoding="utf-8") as f:
@@ -23,29 +23,28 @@ def import_to_raw_json(data:dict[str, Any], category: str, key_word: str, page:
2323

2424

2525

26-
def make_extract(category: str, key_word: str, page: int = 1, page_size: int = 100) -> tuple[str,int]:
26+
def make_extract( key_word: str, page: int = 1, page_size: int = 100) -> tuple[str,int]:
2727
params = {
2828
"apiKey": settings.KEY_API,
29-
"country":settings.COUNTRY,
30-
"category":category,
29+
"language":settings.langueage,
3130
"q": key_word,
3231
"pageSize" : page_size,
33-
"page" : page
32+
"page" : page,
33+
"sortBy": settings.sortBy
3434
}
3535
try:
3636
data = r.get(settings.NEWS_URL, params=params, timeout=15)
3737
data.raise_for_status()
3838
payload = data.json()
3939
logger.info(f"raise of status: {data.status_code}")
4040
payload["fetched_at"] = datetime.now().isoformat()
41-
payload["country"] = settings.COUNTRY
42-
payload["category"] = category
41+
payload["language"] = settings.langueage
4342
payload["key_word"] = key_word
4443
articles_count = len(payload.get("articles", []))
4544
if articles_count == 0:
4645
logger.info("There are no more articles")
4746

48-
new_file_name = import_to_raw_json(payload, category, key_word, page)
47+
new_file_name = import_to_raw_json(payload, key_word, page)
4948
return new_file_name, articles_count
5049

5150
except r.exceptions.Timeout:

src/load.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ def load_news(clean_news:str, max_rows: Optional[int] = None)-> int:
1515

1616
query = """
1717
INSERT INTO bad_news_bears (
18-
country,
19-
category,
18+
language,
2019
key_word,
2120
author,
2221
title,
@@ -25,7 +24,7 @@ def load_news(clean_news:str, max_rows: Optional[int] = None)-> int:
2524
published_at,
2625
fetched_at
2726
)
28-
VALUES (%s, %s, %s, %s,%s, %s, %s, %s,%s)
27+
VALUES (%s, %s, %s,%s, %s, %s, %s,%s)
2928
ON CONFLICT (url) DO NOTHING
3029
"""
3130

@@ -34,8 +33,7 @@ def load_news(clean_news:str, max_rows: Optional[int] = None)-> int:
3433
if max_rows is not None and num_of_news >= max_rows:
3534
break
3635
cur.execute(query,
37-
(new["country"],
38-
new["category"],
36+
(new["language"],
3937
new["key_word"],
4038
new["author"],
4139
new["title"],

src/transform.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ def clean_article(data) -> tuple[list[dict[str,str]], dict]:
5858
statistic["accepted_articles"] += 1
5959
clean_data.append(
6060
{
61-
"country": data["country"],
62-
"category": data["category"],
61+
"language": data["language"],
6362
"key_word": data["key_word"],
6463
"author": element["author"],
6564
"title": element["title"],
@@ -71,7 +70,7 @@ def clean_article(data) -> tuple[list[dict[str,str]], dict]:
7170
)
7271
return clean_data, statistic
7372

74-
def transform_article(new_file_name:str,category: str, hot_pot: str, page: int) -> str:
73+
def transform_article(new_file_name:str, key_word: str, page: int) -> str:
7574
extract_dir = BASE_DIR / "raw" / new_file_name
7675
with open(extract_dir, 'r', encoding='utf-8') as f:
7776
data = json.load(f)
@@ -80,8 +79,8 @@ def transform_article(new_file_name:str,category: str, hot_pot: str, page: int)
8079
load_dir = BASE_DIR / "clean"
8180
load_dir.mkdir(parents=True, exist_ok=True)
8281
timestamp = datetime.now().strftime("%Y_%m_%d-%H-%M-%S")
83-
stats_clean_data = f"stats_{category}_{hot_pot}_page_{page}_{timestamp}.json"
84-
create_clean_data = f"cleaned_{category}_{hot_pot}_page_{page}_{timestamp}.json"
82+
stats_clean_data = f"stats_{key_word}_page_{page}_{timestamp}.json"
83+
create_clean_data = f"cleaned_{key_word}_page_{page}_{timestamp}.json"
8584
cleaned_file_path = load_dir / create_clean_data
8685
stats_dir = load_dir/ "stats"
8786
stats_dir.mkdir(parents=True, exist_ok=True)

0 commit comments

Comments
 (0)