# добавление папки в которой искать модули
sys.path.append(path)
# определение директории файла
os.path.dirname(path)
# смена рабочей директории
os.chdir(directory)
# переменная, в которой хранится путь до текущего скрипта
__file__
# делаем, чтобы все относительные пути
# вычислялись относительно пути до скрипта
os.chdir(os.path.dirname(__file__))
понедельник, 14 июня 2010 г.
Пути к файлам
суббота, 29 мая 2010 г.
Распознавание captcha.
Решил я научиться распознавать самую простую капчу, какая только существует. Вот она:
. Это png-изображение с размерами 90x25. То есть каждый символ занимает 18 пикселей, всего 5 символов. Весь алфавит этой капчи состоит из 16 символов: 0123456789abcdef. Таким образом мне пришлось собрать все картинки для этого алфавита, нарезать из них буковки, а затем склеить в одну картинку:
. Ну и весь алгоритм сводится к тому, чтобы сравнивать все символы по очереди с алфавитом. Для этого я воспользовался библиотекой PIL:
. Это png-изображение с размерами 90x25. То есть каждый символ занимает 18 пикселей, всего 5 символов. Весь алфавит этой капчи состоит из 16 символов: 0123456789abcdef. Таким образом мне пришлось собрать все картинки для этого алфавита, нарезать из них буковки, а затем склеить в одну картинку:
. Ну и весь алгоритм сводится к тому, чтобы сравнивать все символы по очереди с алфавитом. Для этого я воспользовался библиотекой PIL:from PIL import Image, ImageColor
def cmp_image(img1,img2):
return list(img1.getdata()) == list(img2.getdata())
def decode(img):
# Весь алфавит
bigimg = Image.open(r"all.png")
# Соответсвие букв изображениям
alpha = "0123456789abcdef"
res = ""
for x in xrange(5):
tmp = Image.new('RGB', (18, 25))
tmp.paste( img.crop((x*18,0,x*18+18,25)))
letter = "a"
for y in xrange(16):
ideal = Image.new('RGB', (18, 25))
ideal.paste(bigimg.crop((y*18,0,y*18+18,25)))
rms = cmp_image(ideal,tmp)
if rms:
letter = alpha[y]
break
res += letter
return res
img = Image.open(r"e:\image.png")
print decode(img)
воскресенье, 23 мая 2010 г.
Снова про кодировки.
Прочитал статью. Насчет кодировок в голове всё становится яснее и яснее=) До этого момента в консоль на английском языке сообщения выводил, не хотел связываться. Оказывается всё просто - необходимо получить из строки объект типа юникод и написать print объект. И совсем необязательно вытворять танцы с кодом типа decode('utf8').encode('cp866').
среда, 19 мая 2010 г.
Генерация xml карты.
Иногда требуется сгенерировать xml карту для заданных ссылок. Сначала делал это за счет метода строки format, но вот решил попробовать модуль для работы с xml и набросал простенькую функцию:
import StringIO
from xml.sax.saxutils import XMLGenerator
def create_sitemap(cnagfreq,priority,*links):
st = StringIO.StringIO()
g = XMLGenerator(st,encoding="UTF-8")
g.startDocument()
g.startElement('urlset', {'xmlns':"http://www.sitemaps.org/schemas/sitemap/0.9"})
for lnk in links:
g.characters("\n")
g.startElement("url", {})
g.characters("\n")
g.startElement("loc", {})
g.characters(lnk)
g.endElement("loc")
g.characters("\n")
g.startElement("changefreq", {})
g.characters(cnagfreq)
g.endElement("changefreq")
g.characters("\n")
g.startElement("priority", {})
g.characters(priority)
g.endElement("priority")
g.characters("\n")
g.endElement("url")
g.characters("\n")
g.endElement("urlset")
g.endDocument()
return st.getvalue()
lst = ["http://ya.ru/{0}.html".format(x) for x in xrange(5)]
print create_sitemap("daily","0.8",*lst)
вторник, 12 января 2010 г.
Полезные модули.
Нашел под python много интересных модулей.
- Markovgen - генерация текста, цепями Маркова, не помню где взял, думаю автор не обидится если не укажу ссылку.
- ClientForm- классная вещь, позволяет автоматически формировать POST-запрос для html-форм на странице. На том же сайте есть и mechanize, вроде как еще одна приблуда типа urllib-ов и httplib-ов, с отличием, что эмулирует браузер. Не разбирался с ним, помню только, что когда запустил пример с сайта в сниффере увидел, что скрипт полез искать robots.txt.
- Beautiful Soup -модуль для работы с html-кодом страницы. Пользовался им, когда не знал про ClientForm, для того, чтобы выдернуть все данные формы.
- PIL -модуль для работы с изображениями, пользовался пару раз, для того, чтобы склеить капчу и для того, чтобы уникализировать заливаемые изображения.
- libgmail - как-то наткнулся на него, пару раз попробовал приконнектиться к почте, но безуспешно. Модуль, конечно, МастХэв, но, то ли я что-то упустил, то ли он устарел.
- wodrpesslib - когда-то писал скрипт, для автопостинга в Wordpress, наткнулся на этот модуль, к сожалению он работает только через xmlrpc, что не всегда приемлимо.
вторник, 6 октября 2009 г.
Пул потоков. Модуль Threading.
Я думаю, пример из SEO-софта на тему пула потоков долго искать не придется. Взять тот же Хрумер. Указал количество потоков, например 20, запустил - все 20 работают, как только один из них завершит работу - запускается следующий и так, пока не закончатся ссылки. Наверное в 9 из 10 случаев я пишу скрипт с использованием пула потоков. Рассмотрим некторые примеры.
Пример 1. "В лоб".
Функцию step_one запускаем в несколько потоков, все созданные потоки храним в списке. Затем провереяем в цикле какие потоки завершили работу и, если такие есть, создаем новые и так, пока не достигнем какого-либо результата. Криво, неудобно, зато сразу понятно. Достаточно долго пользовался такой реализацией, а всё из-за лени.
Пример 2. Семафоры.
Уже лучше, количество потоков контролируется, но надо заранее знать сколько будет потоков, в общем как-то изворачиваться если тебе надо будет прервать все эти потоки по условию.
Пример 3. Очереди.
Здесь используется модуль Queue. На данный для меня самый удобный варинат - и выглядит красиво, и данные передавать можно.
Помимо тех вариантов, что я описал, можно погуглить на тему threadpool и найти какие-нибудь модули для организации пула потоков.
Пример 1. "В лоб".
threads = []
for x in range(THREADS):
new_thread = threading.Thread(target=step_one)
threads.append(new_thread)
new_thread.start()
time.sleep(1)
while True: # какое-то условие
for y in threads[:]:
if not y.isAlive():
threads.remove(y)
new_thread = threading.Thread(target=step_one)
threads.append(new_thread)
new_thread.start()
time.sleep(0.1)
while threading.activeCount()>0:
time.sleep(5)
Функцию step_one запускаем в несколько потоков, все созданные потоки храним в списке. Затем провереяем в цикле какие потоки завершили работу и, если такие есть, создаем новые и так, пока не достигнем какого-либо результата. Криво, неудобно, зато сразу понятно. Достаточно долго пользовался такой реализацией, а всё из-за лени.
Пример 2. Семафоры.
import time
import threading
max_potokov = 20
maxconnections = 5
akkiQueue = threading.BoundedSemaphore(value=maxconnections)
def doform():
akkiQueue.acquire()
# код функции
akkiQueue.release()
for i in xrange(max_potokov):
time.sleep(1)
p = threading.Thread(target=doform)
p.setDaemon(True)
p.start()
while threading.activeCount()>0:
time.sleep(5)
Уже лучше, количество потоков контролируется, но надо заранее знать сколько будет потоков, в общем как-то изворачиваться если тебе надо будет прервать все эти потоки по условию.
Пример 3. Очереди.
queue = Queue.Queue() # создаем очередь
def register(item):
#Функция с основным кодом
return
def repeat():
while True:
try:
item = queue.get_nowait() # ждём данные
except Queue.Empty:
break
register(item) # передаем данные в нашу функцию
time.sleep(0.5)
queue.task_done() # задача завершена
for item in range(MAX_THREADS):
queue.put(item) # заносим данные в очередь
for i in xrange(THREADS):
t = threading.Thread(target=repeat) # создаем нить
t.start() # стартуем
time.sleep(0.5)
queue.join() # блокируем очередь до завершения
Здесь используется модуль Queue. На данный для меня самый удобный варинат - и выглядит красиво, и данные передавать можно.
Помимо тех вариантов, что я описал, можно погуглить на тему threadpool и найти какие-нибудь модули для организации пула потоков.
четверг, 17 сентября 2009 г.
Странные cookies гугла.
Вот такие вот: __utma=199306621.1164773483.1250671648.1250671648.1250671648.1; __utmb=199306621; __utmc=199306621; __utmz=199306621.1250671648.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
Много раз уже их видел, не придаю им значения, вроде бы это куки для google-analytcs, ну не мешают и ладно, однако один раз помешали. Точнее даже два. Писал регалку, сайт без них выдавал только заголовок, без тела страницы. Я сначала было отчаялся, но потом добавил curl.setopt(pycurl.COOKIE,'вся эта зеленая хрень') и обманул сайт. Но как-то странно, если у пользователя на этом сайте будет отключен java-script, он подумает что сайт глючит.
Много раз уже их видел, не придаю им значения, вроде бы это куки для google-analytcs, ну не мешают и ладно, однако один раз помешали. Точнее даже два. Писал регалку, сайт без них выдавал только заголовок, без тела страницы. Я сначала было отчаялся, но потом добавил curl.setopt(pycurl.COOKIE,'вся эта зеленая хрень') и обманул сайт. Но как-то странно, если у пользователя на этом сайте будет отключен java-script, он подумает что сайт глючит.
Подписаться на:
Сообщения (Atom)