Отбираем валидные мобильные номера друзей VK на Python

от автора

В процессе изучения Python стало интересно попробовать его в связке с API VK. В ВК есть телефонная книга, она показывает телефоны ваших друзей в более-менее удобном формате. Так как далеко не всегда люди охотно оставляют там полые(валидные) номера своих телефонов, мне показалась интересной идея написать скрипт, который отбирал бы только валидные номера моб.телефонов и выдавал бы их отдельной таблицей. Наша телефонная книга будет генерировать csv-файл, который затем можно будет открыть, например, в excel.

Для использования API VK на Python я нагуглил отличную, на мой взгляд, библиотеку с оригинальный названием vk.
Итак, импортируем необходимые модули:

import vk from time import sleep from re import sub, findall from getpass import getpass from csv import writer, QUOTE_ALL 

Создадим класс User с необходимыми методами:

class User(object): 	"""VK User""" 	def __init__(self, login, password): 		self.login = login 		self.password = password 		self.id = '' 	# аторизирует юзера 	def auth(self): 		session = vk.AuthSession(app_id='5340228', user_login=self.login, user_password=self.password) 		api = vk.API(session) 		return api 	# возвращает массив объектов друзей 	def friends(self, api):                 # возвращает в том порядке, в котором расположены в разделе Мои 		user_friends = api.friends.get(user_id=self.id, order='hints') 		return user_friends 	# возвращает количество друзей 	def friends_count(self, api): 		user_friends = User.friends(self, api) 		friends_count = len(user_friends) 		return friends_count 	# возвращает массив данных о юзере 	def info(self, api): 		user = api.users.get(user_id=self.id) 		return user[0]

Долго не мог решить проблему, и в гугле как-то не попадалось на глаза, как взять id текущего пользователя. По счастливой случайности нашел выход — надо передать в качестве аргумента пустую строку.

Далее напишем функцию валидатор, которая будет приводить мобильные номера к общему виду. Мне, как жителю Украины, интересно выбирать только украинские моб.номера, которые должны начинаться на «0». Скрипт легко подправить под любой формат.

def norm_mob(str): 	if len(str) != '': 		norm_mob = sub(r'(\s+)?[+]?[-]?', '', str) 		# проверяем строку на наличие в ней только необходимых символов 		right_mob = findall(r'[\d]', norm_mob) 		# если количество знаков в двух строках совпадает, значит это номер телефона 		if (len(right_mob) == len(norm_mob)) and (len(norm_mob) >= 10): 			rev_norm_mob = norm_mob[::-1] 			norm_mob = rev_norm_mob[0:10] 			if norm_mob[::-1][0] == '0': 				return norm_mob[::-1] 	else: 		return False

Далее проходим по друзьям, выбираем тех, кто оставлял свои контакты, и если оставлял, то валидируем их и записываем в массив. Сервер ВК не любит большого количества запросов, поэтому заставим наш скрипт спать некоторое время между ними, пробовал разные значения, оптимальными оказались эти.

def find_correct_phone_numbers(api, friends, friends_count): 	users_phones = [] 	for i in range(0, friends_count): 		cur_user_id = int(friends[i]) 		cur_user = api.users.get(user_id=cur_user_id, fields='contacts') 		try: 			# выбираем номер мобильного телефона 			cur_mob = cur_user[0]['mobile_phone'] 		except KeyError: 			sleep(0.3) 			continue 		mob = norm_mob(cur_mob) 		if mob: 			# вставим еще одну строку в наш массив 			users_phones.append({ 				'user_name': '{} {}'.format(cur_user[0]['first_name'], cur_user[0]['last_name']), 				'user_phone': '8{}'.format(mob) 				}) 		sleep(0.4) 	return users_phones 

Сохраняем полученный результат.

def saveCSV(data, path):     with open(path, 'w') as csvfile:         my_writer = writer(csvfile, delimiter='	', quotechar='"', quoting=QUOTE_ALL)         my_writer.writerow(('Имя пользователя', 'Номер моб. телефона'))         for item in data:         	try:         		my_writer.writerow((item['user_name'], item['user_phone']))         	except Exception:         		my_writer.writerow(('(Ошибка в кодировке)', item['user_phone'])) 

Добавим функцию, которая считала бы затраченное время.

class Timer(object):     def __enter__(self):         self._startTime = time()     def __exit__(self, type, value, traceback):     	howLong = time() - self._startTime     	print("Операция заняла: {:.2f} минут".format(howLong/60)) 

Ну и заключительный этап, сделаем вызов написанных функций.

def main(): 	while True: 		login = input('E-mail: ') 		password = getpass('Password: ') 		try: 			vk_user = User(login, password) 			api = vk_user.auth() 			print('Авторизация выполнена успешно!') 			break 		except Exception: 			print('Вы ввели неверные данные, пожалуйста, повторите попытку.') 	friends = vk_user.friends(api) 	friends_count = vk_user.friends_count(api) 	print('Найдено {} друзей.'.format(friends_count)) 	print('Идет выборка мобильных номеров...') 	with Timer() as p: 		users_phones = find_correct_phone_numbers(api, friends, friends_count) 	print('Выборка окончена. Сохранение...') 	saveCSV(users_phones, 'vk_mob.csv') 	print('Данные успешно сохранены.') if __name__ == '__main__': 	main() 

На выходе получаем csv-файл, который можно открыть в excel в формате удобной таблицы.

ссылка на оригинал статьи https://habrahabr.ru/post/279803/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *