Кстати, а почему бы мне его не применить))
В общем вот что получилось в итоге:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver=webdriver.PhantomJS()
driver.get('http://spb.superjob.ru')
#print driver.title - проверим был ли переход можно тут, а можно и try/except
loginform=driver.find_element_by_class_name('LoginForm_link')
loginform.click()
driver.find_element_by_id('LoginForm_login').send_keys('username@mail(dot)domain')
driver.find_element_by_id('LoginForm_password').send_keys('password')
driver.find_element_by_id('LoginForm_password').send_keys(Keys.ENTER)
driver.find_element_by_link_text(u'Моё резюме').click()
driver.find_element_by_link_text(u'обновить дату публикации').click()
driver.quit()
*меня тут прибило искать форму с сабмитом и я использовал тот факт, что клавиша ВВОД обычно и есть "submit", но можно было и через вот это попробовать - это более канонично.
find_element_by_name("submit").click()
Все очень даже просто и понятно.
Задача для развития:
сделать тоже самое используя файл с coockies, Плюс куков в том, что парольи не хранятся в открытом виде, ну и вообще.
http://selenium-python.readthedocs.org/
http://www.ibm.com/developerworks/ru/library/l-python-mechanize-beautiful-soup/
http://wwwsearch.sourceforge.net/mechanize/
http://habrahabr.ru/post/65383/
have a fun
================ UPDATED 13.01.15 ======================
Ребром встал вопрос о сокрытии паролей внутри программы. Даже компиляция в .pyc-файл не очень тут спасает, потому как при просмотре файла внутри .pyc отлично видны такие вещи как username@mail(dot)domain, ну а прикинуть что из текста будет паролем - вообще несложно.
Можно конечно использовать модуль base64, он тоже кодирует, но на глаз сразу видны кодированные строки и раскодировать их вообще "нипраблема". Покопавшись и почитав я принял решение подключить модуль crypto и выбрав какой-либо метод шифрования, хитрый ключ и размер блока, шифрануть все что надо. Вот что в итоге получилось
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from base64 import b64decode,b64encode
from sys import exit
""" URL, LOGIN, PASSWD -сгенеренные от ключа numkey http://spb.superjob.ru, login+password"""
numkey=1234567890123456
URL='XmwrgNWXKqkkoRJDgC020R7Uq9RfuJsgey6mcfGYCug='
LOGIN='n5sr2mgr7Kj7cSnp/p1Z8qKbMqsR0VG0Z62fpJB3VrU='
PASSWD='+hS577+JJ1+w91wO7KH4n1Q=='
BLOCK_SIZE = 16
PADDING = '{'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(b64decode(e)).rstrip(PADDING)
cipher = AES.new(str(numkey))
driver=webdriver.PhantomJS()
# ожидание загрузки страницы зависит от скорости инета/компа..
# да и еще PhantomJS - достаточно тормознутая хрень, делаем неявное ожидание 20 секунд
driver.implicitly_wait(20)
"""
можно по-другому, например до появления како-то элемента
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get('...')
// wait for svg to appear
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.TAG_NAME, 'svg')))
"""
#заключам весь процесс в секцию try/except - неизвестно на каком этапе срубится, может
#пароль сменим внезапно.. ;)
retcode=0
try:
driver.get(DecodeAES(cipher,URL))
loginform=driver.find_element_by_class_name('LoginForm_link')
loginform.click()
driver.find_element_by_id('LoginForm_login').send_keys(DecodeAES(cipher,LOGIN))
driver.find_element_by_id('LoginForm_password').send_keys(DecodeAES(cipher,PASSWD))
driver.find_element_by_id('LoginForm_password').send_keys(Keys.ENTER)
driver.find_element_by_link_text(u'Моё резюме').click()
driver.find_element_by_link_text(u'обновить дату публикации').click()
except:
retcode=1
driver.quit()
exit(retcode)
скомпилировав это чудо через
import py_compile
py_compile.compile('myfile.py')
я получил вполне достойный псевдобинарник, где нет видных глазу данных. Конечно, я же этот бинарник могу сломать, но не зная как выглядит ключ это нетривиально, что и требовалось.
Ни о какой сверхЪзащите здесь речи и не шло. С другой стороны, для усложнения поиска ключа, итоговый ключ можно было разнести на несколько переменных смешанных со статическими данными. Типа такого:
cr1='.-.+.\./'
cr2=random.randint(1000000000000000,9999999999999999)
cr3='$}887zO`'
размерность ключа должна быть кратной 8ми, а итоговый ключ может выглядеть так
key=cr3+str(random.randint(10000000,99999999))+cr1+cr2
что в .pyc будет выглядеть несовсем понятно.
литература:
https://www.dlitz.net/software/pycrypto/
http://selenium2.ru/docs/webdriver-advanced-usage.html
================ UPDATED 23.04.15 ======================
def superjobupdate(driver, cipher, SJURL, SJLOGIN, SJPASSWD):
retcode=0
try:
driver.get(DecodeAES(cipher,SJURL))
driver.find_element_by_class_name('LoginForm_link').click()
driver.find_element_by_id('LoginForm_login').send_keys(DecodeAES(cipher,SJLOGIN))
driver.find_element_by_id('LoginForm_password').send_keys(DecodeAES(cipher,SJPASSWD)+Keys.ENTER)
driver.find_element_by_xpath('//*[@id="ng-app"]/div[2]/div/div[2]/div/div[1]/div[3]/div[2]/div[1]/a').click()
driver.find_element_by_link_text(u'обновить дату публикации').click()
except:
retcode=2
return retcode
def hhupdate(driver, cipher, HHURL, HHLOGIN, HHPASSWD):
retcode=0
try:
driver.set_window_size(1400,1000)
driver.get(DecodeAES(cipher,HHURL))
driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/div[2]/form/label[1]/input').send_keys(DecodeAES
driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/div[2]/form/label[2]/input').send_keys(DecodeAES
driver.get(DecodeAES(cipher,HHURL)+'/applicant/resumes')
arr=driver.find_elements_by_class_name("resumelist__resume")
maxresumes=len(arr)
for resumeindex in range(0,maxresumes):
el=arr[resumeindex].find_element_by_class_name('b-resumelist-vacancyname')
el.click()
try:
driver.find_element_by_css_selector('body > div.HH-MainContent > div.g-row.m-row_content > div.g-col
except:
pass
driver.back()
arr=driver.find_elements_by_class_name("resumelist__resume")
except:
retcode=20
return retcode