def select_telegram_group():
    '''
    '''

    # Collega il client Telegram
    with tg_functions.connect_telegram_client(
            password_manager.tg_phone, password_manager.tg_api_id,
            password_manager.tg_api_hash) as tg_client:
        # Ottiene tutte le conversazioni a cui il profilo è connesso
        list_conversations = tg_functions.get_all_conversations(
            tg_client, only_groups=True)

    # Menu di selezione del gruppo da analizzare
    print(colored('[TELEGRAM]', 'cyan') + ' Selezione gruppo da analizzare:')
    i = 0
    for conv in list_conversations:
        conv_name = generic.only_ASCII(conv[0].title).strip()
        print(
            colored('[', 'red') + str(i) + colored(']', 'red') +
            ' {}'.format(conv_name))
        i += 1

    # Lascia selezionare all'utente il gruppo da analizzare
    print(colored('[TELEGRAM]', 'cyan') +
          ' Inserisci il numero del gruppo da analizzare: ',
          end='')  # Senza ritorno a capo per mettere l'imput sulla stessa riga
    conv_index = input()  # I colori ANSI non funzionano con input()
    target_group = list_conversations[int(conv_index)]
    group_name = generic.only_ASCII(target_group[0].title).strip()
    print(
        colored('[TELEGRAM]', 'cyan') +
        ' E\' stato selezionato il gruppo: {}'.format(group_name))

    return target_group
Beispiel #2
0
    def login(self, username, password):
        '''
        Esegue il login a Instagram usando le credenziali

        Params:
        @username: Nome utente dell'account Instagram a cui connettersi
        @password: Password dell'account Instagram a cui connettersi

        Return:
        True se la connessione é avvenuta con successo, False altrimenti
        '''

        # Se é giá istanziato termina l'oggetto e lo ricrea
        if self.is_initialized:
            self.terminate()

        if self._connect_instagram_client(username, password, anonymous=False):
            self.is_initialized = True
            self.is_logged = True
            if self._logger is not None:
                self._logger.info(
                    'Instagram client correctly started (user {})'.format(
                        generic.only_ASCII(username)))
            return True
        else:
            return False
Beispiel #3
0
    def find_user_by_keywords(self, *keywords, max_profiles=10):
        '''
        Cerca dei profili Instagram in base alle parole chiave usate

        Params:
        @keyords: Nome utente dell'utente da trovare
        @max_profiles: NUmero massimo di profili da ottenere

        Return:
        Lista di profili individuati
        '''

        try:
            # Unisce le keywords
            keywords = [str(i) for i in keywords if i is not None]
            keyword = ' '.join(keywords).strip()
            if keyword == '':
                return []

            # Ricerca i profili
            results = instaloader.TopSearchResults(self._ig_client.context,
                                                   keyword)
            profiles = [profile for profile in results.get_profiles()]

            # Limita il numero di profili
            if len(profiles) > max_profiles:
                profiles = profiles[:10]

            if self._logger is not None:
                self._logger.info('Found {} profiles with keywords {}'.format(
                    len(profiles), generic.only_ASCII(keyword)))
            return profiles
        except Exception as ex:
            self._manage_error(WEBDRIVER_GENERIC_ERROR, ex)
            return []
Beispiel #4
0
def _select_telegram_group():
    '''
    Elenca tutti i gruppi a cui l'utente sta partecipando e gli permette di selezionarne uno

    Return:
    Gruppo selezionato (Telethon entity) o None se si vuole riprendere una sessione precedente
    '''

    # Collega il client Telegram
    with tg_functions.connect_telegram_client(password_manager.tg_phone, password_manager.tg_api_id, password_manager.tg_api_hash) as tg_client:
        # Ottiene tutte le conversazioni a cui il profilo è connesso
        list_conversations = tg_functions.get_all_conversations(
            tg_client, only_groups=True)

    # Menu di selezione del gruppo da analizzare
    print(colored('[TELEGRAM]', 'cyan') +
          ' Selection of Telegram group to analyze:')
    i = 0
    for conv in list_conversations:
        conv_name = generic.only_ASCII(conv[0].title).strip()
        print(
            colored(
                '[',
                'red') +
            str(i) +
            colored(
                ']',
                'red') +
            ' {}'.format(conv_name))
        i += 1

    # Lascia selezionare all'utente il gruppo da analizzare
    print(
        colored(
            '[TELEGRAM]',
            'cyan') +
        ' Enter the index of the group to be analyzed: ',
        end='')  # Senza ritorno a capo per mettere l'imput sulla stessa riga
    conv_index = input()  # I colori ANSI non funzionano con input()

    target_group = list_conversations[int(conv_index - 1)][0]
    group_name = generic.only_ASCII(target_group.title).strip()
    print(colored('[TELEGRAM]', 'cyan') +
          ' Selected Telegram group: {}'.format(group_name))
    _scrape_logger.info('Selected Telegram group: {}'.format(group_name))

    return target_group
Beispiel #5
0
    def get_location_history(self, ig_profile):
        '''
        Ottiene tutti i geotag dei post per uno specifico profilo Instagram.
        E' necessario essere loggati per usare questa funzione.

        Params:
        @ig_profile: Profilo Instagram (Instaloader) di cui recuperare i geotag

        Return:
        Lista di localitá (classes.location) individuate
        '''

        # Variabili locali
        locations_list = []

        # E' necessario essere loggati per usare questa funzione
        if not self.is_logged:
            self._manage_error(USER_NOT_LOGGED, None)
            return []

        # Ottiene l'elenco dei post del profilo Instagram
        try:
            post_list = ig_profile.get_posts()
        except PrivateProfileNotFollowedException as ex:
            self._manage_error(PRIVATE_PROFILE_NOT_FOLLOWED, ex)
            return []
        except Exception as ex:
            self._manage_error(WEBDRIVER_GENERIC_ERROR, ex)
            return []

        # Salva i geotag dei media selezionati
        post_with_location = [
            post for post in post_list if post.location is not None
        ]
        for post in post_with_location:
            loc = location.location()
            # Ottiene la locazione dalle coordinate
            if post.location.lat is not None and post.location.lng is not None:
                loc.from_coordinates(post.location.lat, post.location.lng,
                                     post.date_utc)
                locations_list.append(loc)
            elif post.location.name is not None:
                loc.from_name(post.location.name, post.date_utc)
                locations_list.append(loc)

        # Ordina la lista dalla locazione più recente a quella meno recente
        locations_list.sort(key=lambda loc: loc.utc_time, reverse=True)

        if self._logger is not None:
            self._logger.info('Found {} locations for user {}'.format(
                len(locations_list), generic.only_ASCII(ig_profile.username)))
        return locations_list
Beispiel #6
0
    def find_user_by_keywords(self, *keywords, max_users=10):
        '''
        Cerca dei profili Twitter compatibili con le parole chiave specificate.

        Params:
        @keywords: Parole chiave da utilizzare per la ricerca
        @max_users [5]: Massimo numero di utenti da ricercare

        Return:
        Lista di profili Twitter (profiles.twitter_profile)
        '''

        # Variabili locali
        usernames = []
        tw_profiles = []

        if not self.is_initialized:
            ex = exceptions.WebDriverNotInitialized(
                'The WebDriver is not initialized, please call the init() function'
            )
            self._manage_error(WEBDRIVER_NOT_INITIALIZED, ex)
            return None

        # Compone l'URL da utilizzare per la ricerca
        keys = [str(s).strip() for s in keywords if s is not None]
        search_string = ' '.join(keys)
        if search_string == '':
            return []
        self._driver.get(SEARCH_PEOPLE_URL.format(search_string))

        # Ricerca gli username degli utenti individuati
        usernames_elms = self._driver.find_elements(By.XPATH,
                                                    RESULTS_USERNAMES_XPATH)

        # Ottiene i link degli utenti
        usernames = [elm.text for elm in usernames_elms]

        # Limita il massimo numero di profili da cercare
        if len(usernames) > max_users:
            usernames = usernames[:max_users]

        # Ottiene i dati dei profili
        for username in usernames:
            p = self.find_user_by_username(username)
            tw_profiles.append(p)

        if self._logger is not None:
            self._logger.info('Found {} profiles with the keywords: {}'.format(
                len(tw_profiles), generic.only_ASCII(','.join(keys))))
        return tw_profiles
Beispiel #7
0
    def _connect_instagram_client(self, username, password, anonymous=True):
        '''
        Crea e connette un client Instagram.
        Se anonymous = True le credenziali non verrano usate (possono essere qualunque valore)

        Params:
        @username: Nome utente del proprio account Instagram
        @password: Password del proprio account Instagram
        @anonymous [True]: Connessione in maniera anonima (senza credenziali)

        Return:
        True se la connessione é avvenuta correttamente, False altrimenti
        '''

        # Crea il client
        ig_client = instaloader.Instaloader(quiet=True,
                                            download_videos=False,
                                            download_comments=False,
                                            compress_json=True,
                                            max_connection_attempts=1)
        # File di salvataggio della sessione
        ig_session_file = 'instagram_session.session'

        # Se è stato specificato un client anonimo non vengono specificate le
        # credenziali
        if anonymous:
            self._ig_client = ig_client
            if self._logger is not None:
                self._logger.info('Successfully connected anonymously')
            return True

        # Se esiste un file di sessione già configurato lo carica
        if os.path.exists(ig_session_file) and not anonymous:
            ig_client.load_session_from_file(username, ig_session_file)
        else:
            try:
                ig_client.login(username, password)
                ig_client.save_session_to_file(ig_session_file)
            except Exception as ex:
                self._manage_error(LOGIN_GENERIC_ERROR, ex)
                return False

        self._ig_client = ig_client
        if self._logger is not None:
            self._logger.info('Successfully connected to user {}'.format(
                generic.only_ASCII(username)))
        return True
Beispiel #8
0
def _scrape_twitter(people, save_people_dir):
    '''
    Esegue l'associazione dei profili delle persone a Twitter

    Params:
    @people: Lista di classes.person a cui associare un profilo Twitter
    @save_people_dir: Cartella dove salvare i file profilo
    '''

    # Istanzia lo scraper per Twitter
    tw_scraper = tw_functions.tw_scraper(_tw_logger)

    _scrape_logger.info('Search for Twitter users')
    for p in tqdm(people, 'Search for Twitter users'):
        # Gestisce l'interruzione della ricerca da parte dell'utente
        if _terminate_program:
            tw_scraper.terminate()
            _end_program()

        _scrape_logger.debug(
            'Search user TW profiles with profile ID {}, name {} {}'.format(
                p.id, p.first_name, p.last_name))

        # Verifica se già esiste un profilo Facebook
        if not len(
                p.get_profiles('Twitter')) > 0 and tw_scraper.is_initialized:
            # Ricerca del profilo Twitter
            result = p.find_twitter_profile(tw_scraper, 'italia')

            if result > 0:
                tqdm.write(
                    colored('[Twitter]', 'white', 'on_cyan') +
                    generic.only_ASCII(
                        ' Identified compatible Twitter profile for {} {} ({} references)'
                        .format(p.first_name, p.last_name, result)))

            # Salva i risultati
            save_path = os.path.join(save_people_dir, '{}.person'.format(p.id))
            pickle.dump(p,
                        open(save_path, 'wb'),
                        protocol=pickle.HIGHEST_PROTOCOL)
            database.set_person_checked(_db_path, p.id, 'Twitter')
Beispiel #9
0
    def find_user_by_keywords(self, *keywords, max_users=5):
        '''
        Cerca dei profili Facebook compatibili con le parole chiave specificate.
        E' necessario aver effettuato il login.

        Params:
        @keywords: Parole chiave da utilizzare per la ricerca
        @max_users [5]: Massimo numero di utenti da ricercare

        Return:
        Lista di profili Facebook (profiles.facebook_profile)
        '''

        # Variabili locali
        usernames = []
        fb_profiles = []
        links = []

        # Controlla se il profilo è bloccato
        if self.is_blocked:
            return []

        # Bisogna essere loggati per cercare gli utenti
        if not self.is_logged:
            ex = exceptions.UserNotLogged('In order to use this function the user need to be logged to Facebook')
            self._manage_error(USER_NOT_LOGGED, ex)
            return []

        # Compone l'URL da utilizzare per la ricerca
        keys = [str(s).strip() for s in keywords if s is not None]
        search_string = '%20'.join(keys)
        if search_string == '':
            return []
        self._driver.get(SEARCH_URL.format(search_string))
        time.sleep(SLEEP_TIME_MEDIUM)
        self._request_manager()

        # Ricerca i link degli utenti individuati
        links = self._driver.find_elements(
            By.CLASS_NAME, FB_SEARCH_PEOPLE_LINK_CLASSNAME)

        # Ottiene i link degli utenti
        links = [link.get_attribute('href')for link in links]

        # Ottiene gli username degli utenti
        for link in links:
            username = link.replace(BASE_URL, '')
            index_question_mark = username.find('?')

            # Valore non trovato, possibile cambiamento nelle URL di Facebook
            if index_question_mark == -1:
                continue
            else:
                username = username[:index_question_mark]

            # Un qualche utente standard?
            if 'profile.php' in usernames:
                usernames.remove('profile.php')

            # Aggiunge il nome utente
            usernames.append(username)

        # Limita il massimo numero di profili da cercare
        if len(usernames) > max_users:
            usernames = usernames[:max_users]

        # Ottiene i dati dei profili
        for username in usernames:
            # Esce dal ciclo se il profilo è bloccato
            if self.is_blocked: break

            # Saltiamo la verifica perchè sappiamo già che i profili esistono
            p = self.find_user_by_username(username, skip_verification=True)
            if p is not None: fb_profiles.append(p)
            time.sleep(SLEEP_TIME_LONG)

        if self._logger is not None:
            self._logger.info(
                'Found {} profiles with the keywords: {}'.format(
                    len(fb_profiles), generic.only_ASCII(','.join(keys))))
        return fb_profiles
Beispiel #10
0
def _scrape_facebook_instagram(people, save_people_dir):
    '''
    Esegue l'associazione dei profili delle persone a Facebook e Instagram.
    Vengono eseguite le associazioni in maniera alternata, così da limitare 
    i casi di blocco degli account o di attesa per troppe richieste.

    Params:
    @people: Lista di classes.person a cui associare un profilo Twitter
    @save_people_dir: Cartella dove salvare i file profilo
    '''

    # Apre il browser per Facebook
    _scrape_logger.info('Creation of Facebook scraper')
    fb_scraper = fb_functions.fb_scraper(_fb_logger)
    fb_scraper.init_scraper(use_proxy=False)
    if not fb_scraper.fb_login(password_manager.fb_email, password_manager.fb_password):
        print(colored('[FACEBOOK]', 'blue', 'on_white') +
              ' Unable to login to Facebook')
        _scrape_logger.error('Unable to login to Facebook')
        fb_scraper.terminate()

    # Crea l'istanza per Instagram
    _scrape_logger.info('Creation of Instagram scraper')
    ig_scraper = ig_functions.ig_scraper(_ig_logger)
    if not ig_scraper.login_anonymously():
        print(colored('[INSTAGRAM]', 'magenta') +
              ' Unable to login to Instagram')
        _scrape_logger.error('Unable to login to Instagram')
        ig_scraper.terminate()

    # Inizia lo scraping
    _scrape_logger.info('Search for Instagram and Facebook users')
    for p in tqdm(people, 'Search for Instagram and Facebook users'):
        # Ottiene il percorso di salvataggio del file
        save_path = os.path.join(save_people_dir, '{}.person'.format(p.id))

        # Se l'utente ha scelto di terminare l'applicazione
        # vengono chiuse le istanze degli scraper
        if _terminate_program:
            fb_scraper.terminate()
            ig_scraper.terminate()
            _end_program()

        _scrape_logger.debug('Search user FB/IG profiles with profile ID {}, name {} {}'
                             .format(p.id, p.first_name, p.last_name))

        # Verifica che il profilo Facebook non sia stato bloccato
        if fb_scraper.is_blocked:
            fb_scraper.terminate()
            tqdm.write(colored('[Facebook]', 'blue', 'on_white') + ' Facebook profile has been blocked, now proceeding with only Instagram...')

        # Verifica se già esiste un profilo Facebook
        if not len(p.get_profiles('Facebook')) > 0 and fb_scraper.is_logged:
            # Ricerca del profilo Instagram
            result = p.find_facebook_profile(fb_scraper, 'italia')
            if result > 0:
                tqdm.write(colored('[Facebook]', 'blue', 'on_white') +
                           generic.only_ASCII(' Identified compatible Facebook profile for {} {} ({} references)'
                                              .format(p.first_name, p.last_name, result)))

            # Salva i risultati
            pickle.dump(p, open(save_path, 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
            database.set_person_checked(_db_path, p.id, 'Facebook')

        # Verifica se già esiste un profilo Instagram
        if not len(p.get_profiles('Instagram')) > 0 and ig_scraper.is_initialized:
            # Ricerca del profilo Instagram
            result = p.find_instagram_profile(ig_scraper)
            if result > 0:
                tqdm.write(colored('[Instagram]', 'magenta') +
                           generic.only_ASCII(' Identified compatible Instagram profile for {} {} ({} references)'
                                              .format(p.first_name, p.last_name, result)))

            # Salva i risultati
            pickle.dump(p, open(save_path, 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
            database.set_person_checked(_db_path, p.id, 'Instagram')

    # Chiude il browser Facebook
    _scrape_logger.info('Facebook WebDriver instance termination')
    fb_scraper.terminate()

    # Chiude il client Instagram
    _scrape_logger.info('Instagram client termination')
    ig_scraper.terminate()