def _find_user_page(self, username): ''' Cerca la pagina principale di un utente per verificare che un utente esiste. Params: @username: Nome utente del profilo Return: True se il profilo esiste, False altrimenti ''' # 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 False # Cerca il profilo tramite URL self._driver.get(PROFILE_URL.format(username)) time.sleep(SLEEP_TIME_MEDIUM) self._request_manager() # Aspetta per vedere se viene trovata la pagina di errore wait = WebDriverWait(self._driver, self._timeout) try: wait.until( EC.presence_of_element_located( (By.XPATH, IMAGE_USER_XP))) return True except TimeoutException: return False # Nessun utente trovato except Exception as ex: self._manage_error(WEBDRIVER_GENERIC_ERROR, ex) return False
def download_profile_photo(self, fb_profile, save_path): ''' Scarica l'immagine profilo dell'utente specificato. E' necessario aver effettuato il login. Params: @fb_profile: Profilo Facebook (profiles.facebook_profile) di cui scaricare l'immagine profilo @save_path: Percorso di salvataggio dell'immagine Return: True se l'immagine è stata scaricata, False altrimenti ''' # Controlla se il profilo è bloccato if self.is_blocked: return False # Bisogna essere loggati per scaricare le immagini 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 False # Naviga sul profilo dell'utente self._driver.get(PROFILE_URL.format(fb_profile.username)) time.sleep(SLEEP_TIME_MEDIUM) self._request_manager() # Ottiene l'immagine profilo try: wait = WebDriverWait(self._driver, self._timeout) profile_image = wait.until( EC.element_to_be_clickable( (By.CLASS_NAME, PROFILE_PHOTO_CLASSNAME))) except TimeoutException: ex = exceptions.NoProfilePhoto( 'The user does not have a profile photo') self._manage_error(NO_PROFILE_PHOTO, ex) return False except Exception as ex: self._manage_error(WEBDRIVER_GENERIC_ERROR, ex) return False # Ottiene l'URL dell'immagine url = profile_image.get_attribute('src') # Scarica l'immagine return self._image_download(url, save_path)
def download_profile_images(self, fb_profile, save_dir, max_photo=30): ''' Scarica le immagini del profilo utente. E' necessario aver effettuato il login. Params: @fb_profile: Profilo Facebook (profiles.facebook_profile) di cui scaricare le immagini @save_dir: Directory di salvataggio delle immagini @max_photo [30]: Massimo numero di foto da scaricare ''' # Variabili locali url_images = [] # Controlla se il profilo è bloccato if self.is_blocked: return False # Bisogna essere loggati per scaricare le immagini 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 False # Crea la cartella se serve if not os.path.exists(save_dir): os.makedirs(save_dir) # Ottiene i link alle immagini url_images = self._get_photos_link(fb_profile.username) # Limita il numero di foto da scaricare if len(url_images) > max_photo: url_images = url_images[:max_photo] # Scarica le immagini con il formato 'nomeutente_index.jpg' index = 0 for url in url_images: abs_dir = os.path.abspath(save_dir) save_path = os.path.join( abs_dir, '{}_{}.jpg'.format(fb_profile.username, index)) self._image_download(url, save_path) time.sleep(SLEEP_TIME_SHORT) index += 1 return True
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
def find_user_by_username(self, username, skip_verification=False): ''' Cerca un profilo Facebook a partire dal nome utente. E' necessario aver effettuato il login. Params: @username: Nome utente del profilo @skip_verification [False]: Indica se saltare il controllo dell'esistenza del profilo Return: Profilo Facebook (profiles.facebook_profile) o None se il profilo non esiste (o non si è loggati). ''' # Controlla se il profilo è bloccato if self.is_blocked: return None # 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 None # Variabili locali wait = WebDriverWait(self._driver, self._timeout) # Cerca l'utente if not skip_verification: if not self._find_user_page(username): return None # Utente esistente, estrapoliamo i dati.. fb_user = facebook_profile() fb_user.username = username # Naviga nelle informazioni di contatto self._driver.get(INFO_CONTACT_SECTION.format(username)) time.sleep(SLEEP_TIME_MEDIUM) self._request_manager() # Verifica che l'account non sia stato bloccato if self._is_blocked(): ex = exceptions.FacebookAccountBlocked('The account has been blocked, you may have to wait for a day to use your account. The client will now be closed') self._manage_error(ACCOUNT_BLOCKED, ex) return None # Ottiene il nome completo try: fullname_div = wait.until( EC.presence_of_element_located( (By.XPATH, NAME_DIV_XP))) fb_user.full_name = fullname_div.text.strip() except TimeoutException: pass # Ottieni telefono e abitazione try: phone_number_div = wait.until( EC.presence_of_element_located((By.XPATH, PHONE_INFO_XP))) fb_user.phone = phone.phone(phone_number_div.text) except TimeoutException: pass try: location_div = wait.until( EC.presence_of_element_located((By.XPATH, LOCATION_INFO_XP))) fb_user.location = location.location().from_name(location_div.text) except TimeoutException: pass # Naviga e cerca la biografia self._driver.get(BIO_SECTION.format(username)) time.sleep(SLEEP_TIME_MEDIUM) self._request_manager() try: bio_div = wait.until( EC.presence_of_element_located((By.XPATH, BIO_DIV_XP))) fb_user.biography = bio_div.text.strip() except TimeoutException: pass # Ritorna il profilo createo return fb_user