SouJunior / dashboard-midias

Projeto Dashboard de Mídias
1 stars 1 forks source link

[Desenvolvimento do webscraping - LinkedIn] Loop pelas abas #21

Open renata-olivmachado opened 5 months ago

renata-olivmachado commented 5 months ago

Tarefa da Story: https://github.com/SouJunior/dashboard-midias/issues/16

Desenvolver webscraping Python, podendo usar selenium ou outra lib. O webscraping deve logar no LinkedIn, acessar a página do SJ e extrair os dados para o AWS S3.

Moscarde commented 5 months ago

Arquivo da classe ScraperLinkedin no repositório

A função extract_data é responsável por criar um loop com as urls das abas e iterar executando as extrações individualmente:

    def extract_data(
        self, daterange: str = "d365", custom_daterange: list = ["dd/mm/yyyy"]
    ) -> bool:
        """
        Inicia o loop para execução da extração dos dados.

        Args:
            daterange (str): intervalo de datas(d15, d30, d90, d365, custom_date, 1, 15, 30, 90, 365). Padrão d15.
            custom_daterange (list, optional): lista de datas customizadas. Padrão ['dd/mm/yyyy'].

        Returns:
            bool: Retorna True se os dados foram extraídos com sucesso e False caso contrário.
        """
        extraction_urls = [
            f"https://www.linkedin.com/company/{self.company_code}/admin/analytics/updates/",
            f"https://www.linkedin.com/company/{self.company_code}/admin/analytics/visitors/",
            f"https://www.linkedin.com/company/{self.company_code}/admin/analytics/followers/",
            f"https://www.linkedin.com/company/{self.company_code}/admin/analytics/competitors/",
        ]

        for url in extraction_urls:
            self.driver.get(url)

            WebDriverWait(self.driver, 10).until(EC.url_to_be(url))

            if "competitors" in url:
                self.close_competitors_modal_if_open()

            self.get_element(xpath=self.XPATH_BUTTON_EXPORT).click()
            self.get_element(
                xpath=self.XPATH_BUTTON_DATERANGE, force_waiting=True
            ).click()
            sleep(1)
            d15, d30, d90, d365, custom_date = self.get_element(
                xpath=self.XPATH_LI_DATERANGE, multiple=True, force_waiting=True
            )
            daterange_map = {
                "d15": d15,
                "15": d15,
                "d30": d30,
                "30": d30,
                "d90": d90,
                "90": d90,
                "d365": d365,
                "365": d365,
                "custom_date": custom_date,
            }
            daterange_element = daterange_map.get(daterange)
            daterange_element.click()

            if daterange == "custom_date":
                self.select_custom_daterange(custom_daterange)
            # fluxo correto
            # self.get_element(xpath=self.XPATH_BUTTON_EXPORT_MODAL).click()

            # fluxo de testes - Executa apenas um mouse hover
            ActionChains(self.driver).move_to_element(
                self.get_element(xpath=self.XPATH_BUTTON_EXPORT_MODAL)
            ).perform()
            # fim fluxo de testes

            print("Fazendo download da extração de", url.split("/")[-2])

        return True

Outras funções utilizadas dentro de extract_data:

    def get_element(
        self,
        xpath: str,
        origin_element: WebElement = None,
        multiple: bool = False,
        force_waiting: bool = False,
        timeout: int = 10,
    ) -> Union[bool, WebElement, List[WebElement]]:
        """
        Obtém um elemento da pagina.

        Args:
            xpath (str): xpath do elemento.
            origin_element (WebElement, optional): elemento de origem. Padrão None.
            force_waiting (bool, optional): aguarda o elemento estar visível. Padrão False.
            multiple (bool, optional): retorna uma lista. Padrão False.

        Returns:
            Union[bool, WebElement, List[WebElement]]: Elemento ou lista de elementos da página se encontrados ou False.
        """
        origin_element = origin_element or self.driver

        try:
            if force_waiting and not multiple:
                wait = WebDriverWait(origin_element, timeout)
                return wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))

            elif multiple:
                return origin_element.find_elements(By.XPATH, xpath)

            else:
                return origin_element.find_element(By.XPATH, xpath)

        except Exception as e:
            return False
    def select_custom_daterange(self, daterange: list) -> bool:
        """
        Preenche o intervalo de datas customizado.

        Args:
            daterange (list): lista de datas customizadas.

        Returns:
            bool: Retorna True se as datas customizadas foram preenchidas com sucesso e False caso contrário.
        """
        input_range_start = self.get_element(xpath=self.XPATH_INPUT_RANGE_START)
        self.driver.execute_script("arguments[0].focus();", input_range_start)
        self.driver.execute_script("arguments[0].value = '';", input_range_start)
        input_range_start.send_keys(daterange[0])

        input_range_end = self.get_element(xpath=self.XPATH_INPUT_RANGE_END)
        self.driver.execute_script("arguments[0].focus();", input_range_end)
        self.driver.execute_script("arguments[0].value = '';", input_range_end)
        input_range_end.send_keys(daterange[-1])