├── LICENSE
├── README-en.md
├── README.md
├── apikey.py
├── filewrite.py
├── newsapiscript.py
├── printmenu.py
├── requirements.txt
├── stringurl.py
└── txtParse.py
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Gabriel Theophilo de Souza Figueira
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README-en.md:
--------------------------------------------------------------------------------
1 |
2 |
NewsApiScript
3 | This program is intended to be used for searching several news sites at once with an user-provided keyword. It searches through several sites like BBC, CBS, FoxNews and many others. Instructions as follows
4 | This script uses the NewsApi to return several news articles at once. It returns a .txt file with the news, links and additional information. Ideal for research where a large number of articles about a topic are needed.
5 |
6 | Para instruções em PT-BR, acessar o README-ptBr.md
7 |
8 | # Use of this script
9 |
10 | This program requires Python 3.x.x to run
11 |
12 | 1 - To use this python script you need to clone the repository:
13 | ```bash
14 | git clone https://github.com/GabrielTheophilo/NewsApiScript.git
15 | ```
16 | 2 - CD into the directory and install the required libraries with python:
17 | ```bash
18 | python -m pip install requirements.txt
19 | ```
20 | 3 - Open the folder that you just cloned
21 |
22 | 4 - Register a ApiKey for your personal use at [NewsApi](https://newsapi.org/)
23 |
24 | 5 - Open the apikey.py file and add the 32 charachter code after the 'apikey=', i.e 'apikey=YOURAPIKEY_HERE'
25 |
26 | 6 - Run the newsapiscript.py and follow the CLI commands
27 |
28 | IMPORTANT: If you have the free plan on the newsapi website, your search will be limited to ONE page, so when the program asks for the number of pages, make sure to specify "1", or else the API will return an error, with the code "maximumResultsReached".
29 |
30 | 7 - After you run the code, a .json file will be created with the information and links about the news you searched for. Open with any text editor or IDE of your choosing to access the .json information.
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
NewsApiScript
4 |
5 |

6 |
7 |
Este programa é feito para pesquisar diversos canais de notícias com uma palavra chave dada pelo usuário. Ele procura diversos sites como BBC, FoxNews, CBS e muitos outros. Instruções de uso abaixo
8 | Este script consome a NewsApi para trazer diversas notícias de uma vez. Retorna um arquivo .txt com as notícias, links e informações. Ideal para pesquisas onde há a necessidade de pesquisar diversas fontes de uma vez
9 |
10 | For english instructions, please access the README-en.md file
11 |
12 |
13 |
14 |
15 | # Uso deste script
16 |
17 | Este script requer python3.8 ou mais recente para rodar (compatibilidade não testada com versões abaixo)
18 | Para checar os requisitos das bibliotecas, entre no arquivo [requirements.txt](https://github.com/GabrielTheophilo/NewsApiScript/blob/main/requirements.txt)
19 |
20 | 1 - Para usar esse script python primeiramente você precisa clonar o repositório:
21 | ```bash
22 | git clone https://github.com/GabrielTheophilo/NewsApiScript.git
23 | ```
24 |
25 | 2 - Dê um CD no directory e instale as bibliotecas que vamos usar em python:
26 | ```bash
27 | python -m pip install requirements.txt
28 | ```
29 |
30 | 3 - Abra a pasta que você clonou
31 |
32 | 4 - Registre uma chave para a API no site [NewsApi](https://newsapi.org/)
33 |
34 | 5 - Abra o arquivo apikey.py e adicione a chave de 32 caracteres após o 'apikey=', exemplo: 'apikey=SUACHAVEAQUI'
35 |
36 | 6 - Rode o newsapicript.py e siga os comandos do terminal
37 |
38 | 7 - Depois de rodar o código, um arquivo .json será criado com as informações e links sobre o tópico que você pesquisou. Abra com qualquer editor de texto ou IDE de sua preferência para acessar o arquivo .json.
39 |
40 |
--------------------------------------------------------------------------------
/apikey.py:
--------------------------------------------------------------------------------
1 | class ApiKey:
2 | key='apiKey='
3 | def __init__(self):
4 | return print(self.key)
5 |
--------------------------------------------------------------------------------
/filewrite.py:
--------------------------------------------------------------------------------
1 | # Arquivo que contém a lógica de escrita dos arquivos, dividido em duas classes ( -> FolderWrite <- | -> FileWrite <- )
2 | #
3 | # Classe >FolderWrite< não recebe input, é chamada para criar uma pasta no desktop do usuário para armazenar os arquivos que serão gerados
4 | #
5 | # Classe >FileWrite< recebe input (str,*args)
6 | # no qual (str) equivale á string de pesquisa do usuário(para nomear o arquivo de acordo com a pesquisa feita)
7 | # e (*args) equivale aos dados extraídos do arquivo JSON, que foram parseados pelo módulo txtparse e serão escritos dentro do arquivo
8 | #
9 | # ARQUIVOS DEPENDENTES -> txtParse.py
10 |
11 | import os
12 | import os.path
13 |
14 | class Folder:
15 | username = os.getlogin()
16 | def Folder():
17 | try:
18 | os.mkdir(f'C:\\Users\\{Folder.username}\\Desktop\\NewsApiScript')
19 | return 0
20 |
21 | except:
22 | print("Pasta já existente na área de trabalho")
23 | return 1
24 |
25 | def Path():
26 | return (f'C:\\Users\\{Folder.username}\\Desktop\\NewsApiScript')
27 |
28 | class FileWrite:
29 | def OpenFileWriteJson(str,*args):
30 | Folder.Folder()
31 | path = Folder.Path()
32 | try:
33 | file = open(f'{path}\\{str}.json', 'x')
34 | file.write(*args)
35 | file.close()
36 |
37 | except:
38 | file = open(f'{path}\\{str}.json', 'a')
39 | file.write(*args)
40 | file.close()
41 |
42 | def OpenFileWriteTxt(str,*args):
43 | Folder.Folder()
44 | path = Folder.Path()
45 | try:
46 | file = open(f'{path}\\{str}.txt', 'x')
47 | file.write(*args)
48 | file.close()
49 |
50 | except:
51 | file = open(f'{path}\\{str}.txt', 'a')
52 | file.write(*args)
53 | file.close()
54 |
55 | def OpenFileWriteCsv(str,*args):
56 | Folder.Folder()
57 | path = Folder.Path()
58 | try:
59 | file = open(f'{path}\\{str}.csv', 'x')
60 | file.write(*args)
61 | file.close()
62 |
63 | except:
64 | file = open(f'{path}\\{str}.csv', 'a')
65 | file.write(*args)
66 | file.close()
67 |
--------------------------------------------------------------------------------
/newsapiscript.py:
--------------------------------------------------------------------------------
1 | # Arquivo principal(main) que coordena a execução do script. A requisição inicial é feita por meio deste script, que:
2 | # 1 - Chama a função PrintMenu para exibir opções iniciais para o usuário
3 | # 2 - Constrói a url de pesquisa do usuário e armazena na variável
4 | # 3 - Faz a requisição para a Api
5 | # 4 - Guarda as respostas em variáveis(json_data>serializada; data>organizada em json identado)
6 | # 5 - Oferece ao usuário guardar os dados obtidos em texto ou json
7 | # 6 - Termina a execução do programa
8 | #
9 |
10 | import requests
11 | import json
12 | from apikey import ApiKey as ApiKey
13 | from printmenu import PrintMenu
14 | from txtParse import *
15 | from stringurl import *
16 |
17 | if __name__ == '__main__':
18 | PrintMenu.Menu()
19 | url = StringUrl.__init__(StringUrl.StringAll(), StringUrl.StringSort(), StringUrl.LanguageQuery(), StringUrl.Query())
20 | print(url)
21 | response = requests.get(f'{url}')
22 | json_data = response.json()
23 | data = json.dumps(json_data, indent=4)
24 | escolha = str(input("Escolha uma saída para o arquivo --> txt(.txt), json(.json) ou csv(.csv): ").lower())
25 | if escolha=='txt':
26 | TxtParse.txtPrint(data, StringUrl.query)
27 | elif escolha=='json':
28 | TxtParse.jsonPrint(data, StringUrl.query)
29 | elif escolha == 'csv':
30 | TxtParse.csvPrint(data, StringUrl.query)
31 | PrintMenu.EndMenu()
32 |
--------------------------------------------------------------------------------
/printmenu.py:
--------------------------------------------------------------------------------
1 | # Arquivo que contém os menus para interação na linha de comando do terminal
2 | # Classe >PrintMenu< contém as artes que irão compor o menu e, também, os outros menus para auxiliar o usuário na pesquisa
3 | #
4 | # ARQUIVOS DEPENDENTES: newsapiscript.py
5 |
6 | class PrintMenu():
7 | a = (r'''ooooo ooo .o. o8o .oooooo..o o8o .
8 | `888b. `8' .888. `"' d8P' `Y8 `"' .o8
9 | 8 `88b. 8 .ooooo. oooo oooo ooo .oooo.o .8"888. oo.ooooo. oooo Y88bo. .ooooo. oooo d8b oooo oo.ooooo. .o888oo
10 | 8 `88b. 8 d88' `88b `88. `88. .8' d88( "8 .8' `888. 888' `88b `888 `"Y8888o. d88' `"Y8 `888""8P `888 888' `88b 888
11 | 8 `88b.8 888ooo888 `88..]88..8' `"Y88b. .88ooo8888. 888 888 888 `"Y88b 888 888 888 888 888 888
12 | 8 `888 888 .o `888'`888' o. )88b .8' `888. 888 888 888 oo .d8P 888 .o8 888 888 888 888 888 .
13 | o8o `8 `Y8bod8P' `8' `8' 8""888P' o88o o8888o 888bod8P' o888o 8""88888P' `Y8bod8P' d888b o888o 888bod8P' "888"
14 | 888 888
15 | o888o o888o
16 | ''')
17 | b = (r'''888b 888 d8888 d8b .d8888b. d8b 888
18 | 8888b 888 d88888 Y8P d88P Y88b Y8P 888
19 | 88888b 888 d88P888 Y88b. 888
20 | 888Y88b 888 .d88b. 888 888 888 .d8888b d88P 888 88888b. 888 "Y888b. .d8888b 888d888 888 88888b. 888888
21 | 888 Y88b888 d8P Y8b 888 888 888 88K d88P 888 888 "88b 888 "Y88b. d88P" 888P" 888 888 "88b 888
22 | 888 Y88888 88888888 888 888 888 "Y8888b. d88P 888 888 888 888 "888 888 888 888 888 888 888
23 | 888 Y8888 Y8b. Y88b 888 d88P X88 d8888888888 888 d88P 888 Y88b d88P Y88b. 888 888 888 d88P Y88b.
24 | 888 Y888 "Y8888 "Y8888888P" 88888P' d88P 888 88888P" 888 "Y8888P" "Y8888P 888 888 88888P" "Y888
25 | 888 888
26 | 888 888
27 | 888 888 ''')
28 | c = (r''' ___ __ __ __ __ __ __ ___
29 | |\ | |__ | | /__` /\ |__) | /__` / ` |__) | |__) |
30 | | \| |___ |/\| .__/ /~~\ | | .__/ \__, | \ | | |
31 | ''')
32 | d = (r'''888888ba .d888888 oo .d88888b oo dP
33 | 88 `8b d8' 88 88. "' 88
34 | 88 88 .d8888b. dP dP dP .d8888b. 88aaaaa88a 88d888b. dP `Y88888b. .d8888b. 88d888b. dP 88d888b. d8888P
35 | 88 88 88ooood8 88 88 88 Y8ooooo. 88 88 88' `88 88 `8b 88' `"" 88' `88 88 88' `88 88
36 | 88 88 88. ... 88.88b.88' 88 88 88 88. .88 88 d8' .8P 88. ... 88 88 88. .88 88
37 | dP dP `88888P' 8888P Y8P `88888P' 88 88 88Y888P' dP Y88888P `88888P' dP dP 88Y888P' dP
38 | 88 88
39 | dP dP ''')
40 | e = (r''' _ __ ___ _ _____ _ __
41 | / | / /__ _ _______/ | ____ (_) ___/__________(_)___ / /_
42 | / |/ / _ \ | /| / / ___/ /| | / __ \/ /\__ \/ ___/ ___/ / __ \/ __/
43 | / /| / __/ |/ |/ (__ ) ___ |/ /_/ / /___/ / /__/ / / / /_/ / /_
44 | /_/ |_/\___/|__/|__/____/_/ |_/ .___/_//____/\___/_/ /_/ .___/\__/
45 | /_/ /_/ ''')
46 | f = (r'''███╗ ██╗███████╗██╗ ██╗███████╗ █████╗ ██████╗ ██╗███████╗ ██████╗██████╗ ██╗██████╗ ████████╗
47 | ████╗ ██║██╔════╝██║ ██║██╔════╝██╔══██╗██╔══██╗██║██╔════╝██╔════╝██╔══██╗██║██╔══██╗╚══██╔══╝
48 | ██╔██╗ ██║█████╗ ██║ █╗ ██║███████╗███████║██████╔╝██║███████╗██║ ██████╔╝██║██████╔╝ ██║
49 | ██║╚██╗██║██╔══╝ ██║███╗██║╚════██║██╔══██║██╔═══╝ ██║╚════██║██║ ██╔══██╗██║██╔═══╝ ██║
50 | ██║ ╚████║███████╗╚███╔███╔╝███████║██║ ██║██║ ██║███████║╚██████╗██║ ██║██║██║ ██║
51 | ╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝
52 | ''')
53 |
54 | def __init__():
55 | import random
56 | random1 = random.randint(0,5)
57 | if random1==0:
58 | print(PrintMenu.a)
59 | if random1==1:
60 | print(PrintMenu.b)
61 | if random1==2:
62 | print(PrintMenu.c)
63 | if random1==3:
64 | print(PrintMenu.d)
65 | if random1==4:
66 | print(PrintMenu.e)
67 | if random1==5:
68 | print(PrintMenu.f)
69 |
70 | def Menu():
71 | #Main menu to output status choices to users
72 | PrintMenu.__init__()
73 | print("Quais notícias estarão na sua pesquisa?")
74 | print("---------------------------------------")
75 | print("Top Headlines")
76 | print("Tudo")
77 | print("---------------------------------------")
78 |
79 | def EndMenu():
80 | print ("Programa finalizado, seu arquivo foi gerado na Área de Trabalho")
81 | print("*Aperte qualquer tecla para sair*")
82 | str(input(""))
83 |
84 | if __name__=='__main__':
85 | PrintMenu.Menu()
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.25.1
--------------------------------------------------------------------------------
/stringurl.py:
--------------------------------------------------------------------------------
1 | # Arquivo que contém a lógica da construção da URL através de certos inputs que servirão para delimitar o escopo da pesquisa
2 | # Classe StringUrl contém os pedaços da url para ser montada, junto aos termos de pesquisa do usuário e os escopos que serão delimitados durante a execução do programa
3 | #
4 | # ARQUIVOS DEPENDENTES: newsapiscript.py
5 |
6 |
7 | from apikey import ApiKey
8 |
9 | class StringUrl(ApiKey):
10 | key = ApiKey.key
11 | urlTop = 'https://newsapi.org/v2/top-headlines?'
12 | urlAll = 'https://newsapi.org/v2/everything?'
13 | pagesize = 'pageSize=100&'
14 | country = 'country=br&'
15 | language = 'language=pt&'
16 | popularity = 'sortBy=relevancy&'
17 | relevancy = 'sortBy=popularity&'
18 | url = ''
19 | query = ''
20 | def __init__(StringAll, StringSort,LanguageQuery, Query):
21 | if StringAll == '1' or StringAll == '':
22 | StringUrl.url += StringUrl.urlAll
23 | else:
24 | StringUrl.url += StringUrl.urlTop
25 |
26 | if StringSort == '1' or StringSort == '':
27 | StringUrl.url += StringUrl.relevancy
28 | elif StringSort == '2':
29 | StringUrl.url += StringUrl.popularity
30 |
31 | if LanguageQuery == '1':
32 | StringUrl.url += StringUrl.language
33 | StringUrl.url += (f'q={Query}&')
34 | StringUrl.url += StringUrl.pagesize
35 | StringUrl.url += StringUrl.key
36 | StringUrl.query += Query
37 |
38 | return StringUrl.url
39 |
40 | def StringAll():
41 | return str(input('Deseja ver todas as notícias ou apenas as Top-Headlines? || 1 para Todas, 2 para Principais: '))
42 |
43 | def StringSort():
44 | return str(input('Deseja ordernar sua busca? || Digite 1 para Relevância, 2 para Popularidade, 3 para não ordernar: '))
45 |
46 | def Query():
47 | return str(input("Selecione o termo que deseja pesquisar: "))
48 |
49 | def LanguageQuery():
50 | return str(input("Deseja receber notícias apenas em português ou todas? || 1 para Português, 2 para Todas: "))
51 | def ApiKey():
52 | return str(ApiKey.key)
53 |
54 |
--------------------------------------------------------------------------------
/txtParse.py:
--------------------------------------------------------------------------------
1 | # Arquivo que contém a lógica de separação do texto a partir do JSON recebido pela função principal(__init__ do módulo newsapiscript.py que faz requests a uma url e retorna um json)
2 | # Classe >TxtParse< recebe os dados e a string de pesquisa do usuário e divide o json em dados, separados por categorias e organizados para serem "impressos" no arquivo final
3 | #
4 | # ARQUIVOS DEPENDENTES: newsapiscript.py
5 |
6 | import json
7 | from datetime import date
8 | from filewrite import *
9 |
10 | class TxtParse:
11 | def txtPrint(data, query):
12 | try:
13 | wdata = json.loads(data)
14 | jsondata=json.dumps(data)
15 | i = 0
16 | cdata = ''
17 | data_hoje = date.today()
18 | cdata += (f'DATA DA PESQUISA: {data_hoje.day}/{data_hoje.month}/{data_hoje.year}\n')
19 | for x in wdata['articles']:
20 | print(i)
21 | a = wdata['articles'][i]['source']['name']
22 | b = wdata['articles'][i]['author']
23 | c = wdata['articles'][i]['title']
24 | d = wdata['articles'][i]['description']
25 | e = wdata['articles'][i]['url']
26 | f = wdata['articles'][i]['publishedAt']
27 | g = wdata['articles'][i]['content']
28 | i += 1
29 | print(f"{a}\n{b}\n{c}\n{d}\n{e}\n{f}\n{g}\n")
30 | print("--------------------------------------")
31 | cdata += (f"TEXTO{i}\n\n{a}\n{b}\n{c}\n{d}\n{e}\n{f}\n{g}\n\n\n\n\n")
32 | FileWrite.OpenFileWriteTxt(query,cdata)
33 | except UnicodeEncodeError:
34 | print("Algum erro ocorreu durante a gravação em texto, o arquivo será gravado em .json")
35 | FileWrite.OpenFileWriteJson(query, jsondata)
36 |
37 | def jsonPrint(data, query):
38 | FileWrite.OpenFileWriteJson(query, data)
39 |
40 | def csvPrint(data, query):
41 | try:
42 | wdata = json.loads(data)
43 | jsondata=json.dumps(data)
44 | i = 0
45 | cdata = ''
46 | data_hoje = date.today()
47 | cdata += (f'DATA DA PESQUISA: {data_hoje.day}/{data_hoje.month}/{data_hoje.year},Site, Autor, Assunto,Link,Data\n')
48 | for x in wdata['articles']:
49 | print(i)
50 | a = wdata['articles'][i]['source']['name']
51 | b = wdata['articles'][i]['author']
52 | c = wdata['articles'][i]['title']
53 | d = wdata['articles'][i]['description']
54 | e = wdata['articles'][i]['url']
55 | f = wdata['articles'][i]['publishedAt']
56 | g = wdata['articles'][i]['content']
57 | i += 1
58 | print(f"{a},{b},{c},{d},{e},{f},{g}\n")
59 | print("--------------------------------------")
60 | cdata += (f"{i},{a},{b},{c},{e},{f}\n")
61 | FileWrite.OpenFileWriteCsv(query,cdata)
62 | except UnicodeEncodeError:
63 | print("Algum erro ocorreu durante a gravação em texto, o arquivo será gravado em .json")
64 | FileWrite.OpenFileWriteJson(query, jsondata)
65 |
66 |
67 |
--------------------------------------------------------------------------------