Example #1
0
def build_bot():
    """
        Constrói a base do bot com todos os scrapers cadastrados
    Returns:
        telegram_bot (TelegramBot): Classe do bot
    """
    token = utils.get_config().get(section="telegram", option="BOT_TOKEN")
    contacts_path = os.path.join(utils.get_data_path(), "contacts_list.json")

    scraper_list = [
        MarinhaScraper(
            name="CP-CEM 2021",
            database_path=os.path.join(utils.get_data_path(), "cem2021.json"),
            url=
            "https://www.inscricao.marinha.mil.br/marinha/index_concursos.jsp?id_concurso=401",
        ),
        MarinhaSMVScraper(
            name="SMV 2022",
            database_path=os.path.join(utils.get_data_path(), "smv2022.json"),
        ),
        FundepScraper(
            name="Fundep",
            database_path=os.path.join(utils.get_data_path(), "fundep.json"),
        ),
        CorridasBRScraper(
            name="CorridasBR",
            database_path=os.path.join(utils.get_data_path(),
                                       "corridasbr.json"),
            base_url="http://www.corridasbr.com.br/MG/",
            table_url=
            "http://www.corridasbr.com.br/MG/por_regiao.asp?regi%E3o=Metropolitana%20de%20Belo%20Horizonte",
            max_distance=5,
        ),
        PCIScraper(
            name="PCI Concursos",
            database_path=os.path.join(utils.get_data_path(), "pci.json"),
            store_size=7,
            keywords=[
                "automacao",
                "eletrica",
                "eletricidade",
                "eletronica analogica",
                "eletronica digital",
                "eletrotecnica",
                "engenharia elet",
                "engenheiro elet",
                "marinha",
                "telecom",
            ],
            ignore_words=["estagio", "estagiario", "aprendiz", "suspens"],
        ),
    ]

    telegram_bot = TelegramBot(token=token,
                               scraper_list=scraper_list,
                               contacts_path=contacts_path)

    return telegram_bot
Example #2
0
import time

from Concursobo import utils
from Concursobo.concursobo import build_bot

from apscheduler.schedulers.background import BackgroundScheduler

if __name__ == "__main__":
    """
    Runs the pool and send method and send messages only if there is an update
    """
    telegram_bot = build_bot()
    scheduler = BackgroundScheduler()

    timezone = utils.get_config().get(section="timezone",
                                      option="PYTZ_TIMEZONE")
    scheduler.configure(timezone=timezone)

    def job_cem2021():
        telegram_bot.auto_check(scraper_name="CP-CEM 2021")

    def job_smv2022():
        telegram_bot.auto_check(scraper_name="SMV 2022")

    def job_fundep():
        telegram_bot.auto_check(scraper_name="Fundep")

    def job_corridasbr():
        telegram_bot.auto_check(scraper_name="CorridasBR")

    def job_pci():
Example #3
0
    def scrape_page(self):
        """
        Coleta os dados da página da Fundep
        """
        self.logger.info(msg="Acessando a página...")
        webpage = requests.get(url=self.url)

        if webpage.status_code != 200:
            self.logger.info(msg="Não foi possível acessar a página")
            return AcquisitionStatus.ERROR

        self.logger.info(msg="Página acessada, obtendo os dados...")

        soup = BeautifulSoup(markup=webpage.text, features="html.parser")

        jobs_info = soup.find_all("li", {"class": "column column-block"})

        all_jobs = list()

        for job in jobs_info:
            job_title = job.text.split("\n")[1]
            job_description = ""
            for p in job.find_all("p"):
                job_description += p.text
            job_url = None
            for url in job.find_all("a"):
                if "Mais informações" in url.text:
                    job_url = url["href"]

            job_data = {
                "title": job_title,
                "description": job_description,
                "url": job_url,
            }
            all_jobs.append(job_data)

        self.logger.info(msg=f"{len(all_jobs)} vagas capturadas")

        timezone = pytz.timezone(
            zone=utils.get_config().get(section="timezone", option="PYTZ_TIMEZONE")
        )
        current_time = datetime.now(tz=timezone)

        with open(file=self.db_path, mode="r") as f:
            stored_data = json.load(f)

        output_data = {
            "url": self.url,
            "acquisition_date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "all_jobs": all_jobs,
            "last_update": stored_data["last_update"],
        }

        self.logger.info(
            msg="Comparando com a aquisição do dia "
            + stored_data["acquisition_date"]
            + "..."
        )

        update_added, update_removed = utils.list_difference(
            list_A=all_jobs, list_B=stored_data["all_jobs"]
        )

        if len(update_added) == 0 and len(update_removed) == 0:
            self.logger.info(msg="Nenhuma alteração encontrada")

            with open(file=self.db_path, mode="w") as f:
                json.dump(output_data, f, indent=4)

            return AcquisitionStatus.UNCHANGED

        if update_added:
            self.logger.info(msg=f"{len(update_added)} vagas adicionadas!")

        if update_added:
            self.logger.info(msg=f"{len(update_removed)} vagas removidas!")

        last_update = {
            "date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "jobs_added": update_added,
            "jobs_removed": update_removed,
        }

        output_data["last_update"] = last_update

        with open(file=self.db_path, mode="w") as f:
            json.dump(output_data, f, indent=4)

        return AcquisitionStatus.UPDATED
Example #4
0
    def scrape_page(self):
        """
            Coleta os dados da página do concurso da Marinha
        Returns:
            (AcquisitionStatus): Indica o status da aquisição, se houve sucesso e / ou atualização dos dados
        """
        self.logger.info(msg="Acessando a página...")
        webpage = requests.get(url=self.table_url)

        if webpage.status_code != 200:
            self.logger.info(msg="Não foi possível acessar a página")
            return AcquisitionStatus.ERROR

        self.logger.info(msg="Página acessada, obtendo os dados...")

        soup = BeautifulSoup(markup=webpage.text, features="html.parser")

        tables_soup = soup.find_all(name="table", attrs={"width": "700"})

        # Título da página
        title = tables_soup[0].text.replace("\n", "")[:-1]

        rows_soup = tables_soup[1].findAll(name="tr", attrs={"height": "40"})
        races_list = list()

        for row_soup in rows_soup:

            row_data = row_soup.findAll(name="td")

            race_date = datetime.strptime(row_data[0].text, "%d/%m/%Y")
            race_city = row_data[1].text.strip()
            race_title = row_data[2].text.strip()

            if "km" in row_data[3].text:
                race_distances = row_data[3].text.replace("km", "").split("/")
                race_distances = sorted([
                    float(distance.replace(",", "."))
                    for distance in race_distances
                ])
                if self.check_distance(race_distances=race_distances) is False:
                    continue
                distances_str = "/".join([
                    str(d).replace(".0", "").replace(".", ",")
                    for d in race_distances
                ]) + "km"
            else:
                race_distances = [row_data[3].text]
                distances_str = "".join(race_distances)

            race_url = self.base_url + row_data[2].findAll(
                name="a")[0].attrs["href"]

            race_data = {
                "date": race_date,
                "city": race_city,
                "title": race_title + " - " + distances_str,
                "url": race_url,
            }

            races_list.append(race_data)

        self.logger.info(msg=f"{len(races_list)} corridas capturadas")

        timezone = pytz.timezone(zone=utils.get_config().get(
            section="timezone", option="PYTZ_TIMEZONE"))
        current_time = datetime.now(tz=timezone)

        grouped_races = self.group_races(races_list=races_list)

        with open(file=self.db_path, mode="r") as f:
            stored_data = json.load(f)

        output_data = {
            "title": title,
            "url": self.table_url,
            "acquisition_date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "all_races": grouped_races,
            "last_update": stored_data["last_update"],
        }

        self.logger.info(msg="Comparando com a aquisição do dia " +
                         stored_data["acquisition_date"] + "...")

        updated_races = self.compare_new_with_old(
            current_data=grouped_races, stored_data=stored_data["all_races"])

        if len(updated_races) == 0:
            self.logger.info(msg="Nenhuma alteração encontrada")

            with open(file=self.db_path, mode="w") as f:
                json.dump(output_data, f, indent=4)

            return AcquisitionStatus.UNCHANGED

        self.logger.info(msg=f"Alterações encontradas!")

        output_data["last_update"]["date"] = current_time.strftime(
            "%d/%m/%Y %H:%M:%S")
        output_data["last_update"]["races_added"] = updated_races

        with open(file=self.db_path, mode="w") as f:
            json.dump(output_data, f, indent=4)

        return AcquisitionStatus.UPDATED
Example #5
0
    def scrape_page(self):
        """
            Coleta os dados da página de notícias do PCI Concursos
        Returns:
            (AcquisitionStatus): Indica o status da aquisição, se houve sucesso e / ou atualização dos dados
        """
        session = requests.Session()

        current_page = 1
        saved_data = dict()

        while len(saved_data) < self.store_size:
            self.logger.info(msg=f"Acessando a página {current_page}...")
            webpage = session.get(url=self.url + str(current_page))
            if webpage.status_code != 200:
                self.logger.info(msg="Não foi possível acessar a página")
                return AcquisitionStatus.ERROR

            self.logger.info(
                msg=f"Página {current_page} acessada, obtendo os dados...")

            soup = BeautifulSoup(markup=webpage.text, features="html.parser")

            page_data = soup.find_all(["h2", "ul"])

            news_date = None
            saved_jobs = list()
            for data in page_data:
                date_match = re.match(pattern=r"[0-9]{2}/[0-9]{2}/[0-9]{2}",
                                      string=data.text)

                if "principal" in data.attrs.get("class",
                                                 list()) and date_match:
                    news_date = datetime.strptime(date_match.string,
                                                  "%d/%m/%Y")
                    saved_jobs = list()

                if "noticias" in data.attrs.get(
                        "class", list()) and (news_date is not None):
                    jobs = data.find_all("a")
                    self.logger.info(
                        f"Processando o dia {str(news_date.date())} (" +
                        str(len(jobs)) + " notícias)...")
                    for job in jobs:
                        self.job_scrape(job=job,
                                        saved_jobs=saved_jobs,
                                        session=session)

                    if saved_jobs:
                        self.logger.info(
                            f"{len(saved_jobs)} notícias encontradas!")

                    if news_date in saved_data:
                        saved_data[news_date].extend(saved_jobs)
                    else:
                        saved_data[news_date] = saved_jobs

                    if len(saved_data) >= self.store_size:
                        break

            current_page += 1

        timezone = pytz.timezone(zone=utils.get_config().get(
            section="timezone", option="PYTZ_TIMEZONE"))
        current_time = datetime.now(tz=timezone)

        with open(file=self.db_path, mode="r") as f:
            stored_data = json.load(f)

        all_jobs = self.process_saved_data(saved_data=saved_data)

        output_data = {
            "url": self.url,
            "acquisition_date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "all_jobs": all_jobs,
            "last_update": stored_data["last_update"],
        }

        self.logger.info(msg="Comparando com a aquisição do dia " +
                         stored_data["acquisition_date"] + "...")

        updated_data = self.compare_new_with_old(
            current_data=all_jobs, stored_data=stored_data["all_jobs"])

        if len(updated_data) == 0:
            self.logger.info(msg="Nenhuma alteração encontrada")

            with open(file=self.db_path, mode="w") as f:
                json.dump(output_data, f, indent=4)

            return AcquisitionStatus.UNCHANGED

        self.logger.info(msg=f"{len(updated_data)} alterações encontradas!")

        output_data["last_update"] = {
            "date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "updated_data": updated_data,
        }

        with open(file=self.db_path, mode="w") as f:
            json.dump(output_data, f, indent=4)

        return AcquisitionStatus.UPDATED
Example #6
0
    def scrape_page(self):
        """
            Coleta os dados da página do concurso da Marinha
        Returns:
            (AcquisitionStatus): Indica o status da aquisição, se houve sucesso e / ou atualização dos dados
        """
        self.logger.info(msg="Acessando a página...")
        webpage = requests.get(url=self.url)

        if webpage.status_code != 200:
            self.logger.info(msg="Não foi possível acessar a página")
            return AcquisitionStatus.ERROR

        self.logger.info(msg="Página acessada, obtendo os dados...")

        soup = BeautifulSoup(markup=webpage.text, features="html.parser")

        # Título da página
        title = soup.find_all(name="h1", class_="page-header")[0].text

        # Tabela das informações
        tables_soup = soup.findAll(name="table", class_="views-table cols-0 table table-hover table-striped")

        message_list = list()

        for table_soup in tables_soup:
            rows_soup = table_soup.findAll(name="tr")

            for row_soup in rows_soup:
                row_data = row_soup.findAll(name="td")
                date = re.sub(pattern=r"[\n\t\xa0]", repl="", string=row_data[0].text)
                message = re.sub(pattern=r"[\n\t\xa0]", repl="", string=row_data[1].text)
                url = row_data[2].findAll(name="a")[0].attrs["href"]
                msg_data = {
                    "date": date.strip(),
                    "message": message.strip(),
                    "url": url,
                }
                message_list.append(msg_data)

        self.logger.info(msg=f"{len(message_list)} mensagens capturadas")

        timezone = pytz.timezone(
            zone=utils.get_config().get(section="timezone", option="PYTZ_TIMEZONE")
        )
        current_time = datetime.now(tz=timezone)

        with open(file=self.db_path, mode="r") as f:
            stored_data = json.load(f)

        output_data = {
            "title": title,
            "url": self.url,
            "acquisition_date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "messages": message_list,
            "last_update": stored_data["last_update"],
            "last_update_date": stored_data["last_update_date"],
        }

        self.logger.info(
            msg="Comparando com a aquisição do dia "
            + stored_data["acquisition_date"]
            + "..."
        )

        updated_messages, _ = utils.list_difference(
            list_A=message_list, list_B=stored_data["messages"]
        )

        if len(updated_messages) == 0:
            self.logger.info(msg="Nenhuma alteração encontrada")

            with open(file=self.db_path, mode="w") as f:
                json.dump(output_data, f, indent=4)

            return AcquisitionStatus.UNCHANGED

        self.logger.info(msg=f"{len(updated_messages)} alterações encontradas!")

        output_data["last_update"] = updated_messages
        output_data["last_update_date"] = current_time.strftime("%d/%m/%Y %H:%M:%S")

        with open(file=self.db_path, mode="w") as f:
            json.dump(output_data, f, indent=4)

        return AcquisitionStatus.UPDATED
    def scrape_page(self):
        """
            Coleta os dados da página do concurso da Marinha
        Returns:
            (AcquisitionStatus): Indica o status da aquisição, se houve sucesso e / ou atualização dos dados
        """
        self.logger.info(msg="Acessando a página...")
        webpage = requests.get(url=self.url)

        if webpage.status_code != 200:
            self.logger.info(msg="Não foi possível acessar a página")
            return AcquisitionStatus.ERROR

        self.logger.info(msg="Página acessada, obtendo os dados...")

        soup = BeautifulSoup(markup=webpage.text, features="html.parser")

        # Título da página
        title = soup.find_all(name="span", class_="header0")[0].text

        # Data do concurso
        raw_date_text = webpage.text.split("Data da Prova")[1]
        split_s = raw_date_text.find("<table")
        split_e = raw_date_text.find("</table")
        date_text = raw_date_text[split_s:split_e]
        date_soup = BeautifulSoup(markup=date_text + "</table>",
                                  features="html.parser")

        exam_date = date_soup.text.replace("\n",
                                           "").replace("\t",
                                                       "").replace("\r", "")

        # Tabela das informações
        info_table_config = {
            "height": "24",
            "width": "46",
            "align": "right",
            "valign": "middle",
        }

        info_table_soup = soup.findAll(name="td", attrs=info_table_config)
        message_list = list()

        for information in info_table_soup:

            contents = information.parent.contents

            info_date = contents[5].get_text()[-8:]
            info_msg = contents[7].contents[1].contents[0].get_text()
            msg_data = {
                "date":
                info_date,
                "message":
                info_msg,
                "url":
                "https://www.inscricao.marinha.mil.br/marinha/" +
                contents[7].contents[1].attrs["href"],
            }

            message_list.append(msg_data)

        self.logger.info(msg=f"{len(message_list)} mensagens capturadas")

        timezone = pytz.timezone(zone=utils.get_config().get(
            section="timezone", option="PYTZ_TIMEZONE"))
        current_time = datetime.now(tz=timezone)

        with open(file=self.db_path, mode="r") as f:
            stored_data = json.load(f)

        output_data = {
            "title": title,
            "url": self.url,
            "acquisition_date": current_time.strftime("%d/%m/%Y %H:%M:%S"),
            "exam_date": stored_data["exam_date"],
            "messages": message_list,
            "last_update": stored_data["last_update"],
            "last_update_date": stored_data["last_update_date"],
        }

        self.logger.info(msg="Comparando com a aquisição do dia " +
                         stored_data["acquisition_date"] + "...")

        updated_messages, _ = utils.list_difference(
            list_A=message_list, list_B=stored_data["messages"])

        if exam_date != stored_data["exam_date"]:
            self.logger.info(
                msg=f"Data do concurso atualizada para: {exam_date}")
            updated_messages.append({
                "date": current_time.strftime("%d/%m/%Y"),
                "message": f"Data do concurso atualizada para: {exam_date}",
                "url": self.url,
            })
            output_data["exam_date"] = exam_date

        if len(updated_messages) == 0:
            self.logger.info(msg="Nenhuma alteração encontrada")

            with open(file=self.db_path, mode="w") as f:
                json.dump(output_data, f, indent=4)

            return AcquisitionStatus.UNCHANGED

        self.logger.info(
            msg=f"{len(updated_messages)} alterações encontradas!")

        output_data["last_update"] = updated_messages
        output_data["last_update_date"] = current_time.strftime(
            "%d/%m/%Y %H:%M:%S")

        with open(file=self.db_path, mode="w") as f:
            json.dump(output_data, f, indent=4)

        return AcquisitionStatus.UPDATED