08.25Заполняем формы используя BeautifulSoup
Она лишь покажет примерный план действий и принцип работы многих универсальных постилок на более "Высокоуровневом" коде". Для того, чтобы скрипт знал какие формы заполнять, нам потребуется база с признаками для заполнения. Я разобью её в 3 файла.
- overlap.txt - не полные совпадения имен полей.
- fullmatch.txt -полные совпадения имен полей.
- ignore.txt - фаил с не изменяемыми полями.
Формат у первых двух файлов: поле|значение
Формат у последнего файла: поле
Чтобы знать куда вставлять не статические данные, а генерируемые потребуются макросы.
В примере я использую 3 макроса: [mail],[comm],[name]. Они будут заменять значение в полях.
#coding:utf-8 from BeautifulSoup import BeautifulSoup import urllib,urllib2,re from urlparse import * class Poster(): def __init__(self): self.load() self.prepare() # Загружаем файлы def load(self): self.fullmatch = open("fullmatch.txt").readlines() self.overlap = open("overlap.txt").readlines() self.ignore = open("ingore.txt").readlines() self.comment = "Comment" # Обрабатываем базы в удобный для чтения формат def prepare(self): for i in xrange(len(self.fullmatch)): temp = {} l,r = self.fullmatch.decode("utf-8","ignore").split("|") temp[l]=r self.fullmatch = None self.fullmatch = temp for i in xrange(len(self.overlap)): temp = {} l,r = self.overlap.decode("utf-8","ignore").split("|") self.overlap = None self.overlap = temp # Обработка макросов def replace(self,data): data = data.replace('[mail]','email@email.ru') data = data.replace('[comm]',self.comment) data = data.replace('[name]','Nick') return data # Определяем полный Url, основываясь на относительном def getact(self,act,url): return urljoin(url,act) # Парсинг страницы и подготовка запроса def parse(self,url): data = urllib2.urlopen(url,timeout=self.timeout).read() # Скачиваем страницу res = re.compile(u"<form .*?>.*?</form>",re.I|re.M|re.S) # Выполняем поиск форм forms = re.findall(res,data) # Для правильного определения нужной нам формы нужен другой алгоритм # Здесь используется очень простой алгоритм, исле в форме найден тэг textarea, то анализировать будем её for form in forms: if form.find('textarea')>=0: data = form break # Так как BeautifulSoup очень чуствителен к ломаному html приходится предварительно обрабатывать его # В данном коде эта обработка пропущена, если код битый то прекращаем обработку try: soup = BeautifulSoup(data) except: return False post = {} # Словарь с пост данными vals = {} # Словарь со всеми параметрами тэга # Поиск action поля в форме, для того, чтобы знать куда отправлять данные. try: act = soup('form')[0]['action'] except: act = url # Определяем полный путь act = self.getact(act,url) # Определяем метод, GET/POST try: method = soup('form')[0]['method'].lower() except: method = 'get' method = method.lower() # Находим все поля в форме с именами Input,textarea listinp = soup('input') listinp.extend(soup('textarea')) # Проходим их в цикле for input in listinp: # Если у поля есть имя if input.has_key('name'): # Получаем все параметры поля vals[input["name"]]= dict(input.attrs) # Если у поля есть значение записываем его # Иначе оставляем пусты if input.has_key('value'): post[input['name']]=input['value'] elif not input.has_key('value'): post[input['name']]='' # Обходим все ключи предварительно подготовленного запроса for key in post.keys(): # Если ключ в списке игнорирования, то не изменяем его if key in self.ignore: continue # Если у поля есть параметр type и его значение hidden, то тоже не изменяем его if vals[key].has_key("type"): if vals[key]["type"].lower()=="hidden": continue # Если в базе полных совпадений есть такое поле, то подменяем его на требуемое значение if self.fullmatch.has_key(key): post[key]=self.fullmatch[key] # Иначе пытаемся найти не полное совпадение else: for kk in self.overlap.keys(): if kk in key: post[key]=self.overlap[kk] # Обрабатывавем макросы for key in post.keys(): post[key]=self.replace(post[key]) # Постинг if method=='post': data = urllib.urlencode(post) resp = urllib2.urlopen(url, data, timeout=self.timeout).read() if method=='get': resp = urllib2.urlopen(url+'?'+urllib.urlencode(post)).read() # Проверка постинга if resp.find(self.comment)>0: return True else: return False P = Poster() P.parse('http://site.com')
Если собирайтесь писать что-то серьёзное, то такие библиотеки использовать не стоит. Они сильно влияют на нагрузку и скорость.
2 Ответов на “Заполняем формы используя BeautifulSoup”
Оставить комментарий