Когда я пытался уйти из ВК, то многие плюшки меня безусловно останавливали. Одной из такой фич был Календарь ВК с днями рождения. Ведь забывать друзей и терять с ним контакт не хотелось, а лента ВК мешала тратить время на более полезные вещи. Поэтому ещё давно я задумывался об экспорте дней рождений из ВК. В конце концов руки дошли до этого и сначала я расскажу, как я это сделал через Python+Selenium, а потом через VK API (ссылка на след запись.)
Задача:
Написать скрипт, который заходит на страницу, открывает календарь, проходит по всем дням рождениям и записывает всё в файл формата ics (iCal). Данный формат поддерживается Apple календарем и Google Calendar.
Код python:
Если вы только знакомитесь с Python+Selenium, то рекомендую посмотреть «Начала«.
Итак, нам понадобятся в одной папке chromedriver.exe и скрипт со следующим содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
import os, re import time from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import NoSuchElementException from selenium.webdriver import ActionChains from time import sleep from time import strftime #функция, проверяющая наличие элемента на страницы def xpath_check(xpath): try: driver.find_element_by_xpath(xpath) except NoSuchElementException: return False return True #функция возвращающая событие с именем друга и его датой рождения def event(date, name): event = """BEGIN:VEVENT DTSTART;VALUE=DATE:%s RRULE:FREQ=YEARLY DESCRIPTION: LOCATION: SEQUENCE:1 STATUS:CONFIRMED SUMMARY:%s TRANSP:TRANSPARENT BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:This is an event reminder END:VALARM END:VEVENT """ event= event % (date, name) return event #начало работы с chromedriver.exe print("\nConnection success...") ## GC опции chrome_Options = webdriver.ChromeOptions() prefs = {"profile.default_content_setting_values.notifications" : 2} chrome_Options.add_experimental_option("prefs",prefs) driver = webdriver.Chrome('chromedriver.exe', chrome_options=chrome_Options) #Входим в соц сеть driver.get("http://vk.com") sleep(5)# ждем 5 секунд driver.find_element_by_id("index_email").send_keys('your@email.ru') #вводим свою почту/телефон (заменить на your@email.ru на свою) sleep(2) pwd = driver.find_element_by_id("index_pass") pwd.send_keys('YoUrPwD') #вводим свой пароль (заменить YoUrPwD на свой пароль) sleep(2) pwd.send_keys(Keys.ENTER) print "Entered to Socnetwork" sleep(7) driver.implicitly_wait(30) # открываем календарь driver.get("http://vk.com/feed?w=calendar") sleep(10) # создаем файл BDs.ics и прописываем его начало ics = open("BDs.ics", 'w') prolog = """BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN METHOD:PUBLISH X-WR-CALNAME:BDs """ ics.write(prolog) #вводим лист из месяцев months = [u'Январь',u'Февраль',u'Март',u'Апрель',u'Май',u'Июнь',u'Июль',u'Август',u'Сентябрь',u'Октябрь',u'Ноябрь',u'Декабрь',] #12 раз совершаем следующие действия for _ in range(12): e = driver.find_element_by_id("bd_calendar_header") #находим заголовок календаря, где прописаны месяц и год month = e.text print month log('\nmonth text found') a=0 for mo in months:#сверяемся с листом месяцев a=a+1 if(re.findall(mo, month)): #если есть вопадение, то присваиваем переменной month значаение а month=a if (len(str(a))==1): # добавляем 0 вначале, если месяц из одной цифры month = '0'+str(a) break print u"Месяц: ", month if(xpath_check("//img[@class='bd_cell_img']")):#если есть хотя бы одно день рождение peopimgs = driver.find_elements_by_xpath("//img[@class='bd_cell_img']")# найти все др и вернуть лист из локаторов sleep(3) for peopimg in peopimgs: #для каждого из листа локаторов print peopimg day = peopimg.get_attribute("onmouseover")# найти в атрибуте день l = re.findall("([0-9]|[0-9][0-9])\);$",day) day = int(l[0][:2]) if(len(str(day))==1): day = '0'+str(day) print day act = ActionChains(driver) # навести мышкой на фото друга и ждать пока появится описание с именем act.move_to_element(peopimg).perform() print "moved" sleep(10) name = driver.find_elements_by_xpath("//div[contains(@class, 'name')]/a[contains(@onclick, 'return')]") # находим имя своего друга #name=u'ДР '+name.text date = strftime("%Y")+str(month)+str(day) #составляем дату события ics.write(event(date,name).encode('utf-8')) # пишем в файл событие driver.find_element_by_xpath("//a[@onclick='Calendar.calGetMonth(1)']").click() # кликаем на стрелку вперед и переходим к следующему месяцу sleep(5) print "Pass to next page" driver.close() # пишем в файл последнюю завершающую строку end=""" END:VCALENDAR """ ics.write(end) ics.close() print "Completed" |
В папке со скриптом появится файл BDs.ics, который можно импортировать в календарь.