22 нояб. 2012 г.

Собираем прокси лист для grab

Grab - фреймворк для парсинга сайтов, умеет работать через прокси сервера. В документации заявлено, что grab в принципе может сам брать сервера из файла-списка, сам может выбирать случайный, сам может менять сервера от запроса к запросу (Grab documentation. Работа с прокси-серверами).
Ниже скрипт для сбора этого списка с spys.ru - так проще, чем собирать список из поисковиков, а потом еще постоянно мониторить не отвалился ли какой-нибудь из серверов.

# -*- coding: utf-8 -*-

import os
import sys
import re
from grab import Grab, GrabError
from urllib import quote
from iptools import validate_ip


def parse():
    g = Grab()
    g.go('http://spys.ru/')
    rex = re.compile(r'(?:(?:[-a-z0-9]+\.)+)[a-z0-9]+:\d{2,4}')
    f = open(os.path.join(sys.path[0], 'proxy_list.txt'), 'w')
    for proxy in rex.findall(g.css_text('body')):
        ip, port = proxy.split(':')

        if len(ip.split('.')[0]) >= 4:  # на spys.ru для секурности дописывают двухсимвольную фигню в начало.
            ip = ip[2:]
            proxy = proxy[2:]

        if validate_ip(ip):
            g.setup(proxy=proxy, proxy_type='http', connect_timeout=5, \
                    timeout=5)
            try:
                g.go('http://www.apple.com/')
                try:
                    h1 = g.xpath_text("//h1")
                    if h1 in ['ERROR', 'Proxy Authentication Required']:
                        continue
                except Exception, e:
                    print e

                if g.response.code == 200:
                    print proxy.ljust(20), 'OK  ', g.response.code
                    f.write(proxy + '\n')

            except GrabError:
                print proxy.ljust(20), 'FAIL'
    f.close()

if __name__ == '__main__':
    parse()

9 нояб. 2012 г.

bitbucket в твоем домене

Не знаю видел ли ты, дорогой читатель, не очень новую, но очень полезную функцию bitbucket - привязка своего домена? Вместе с командными кабинетами эта функция позволяет за считанные секунды создать для команды общее хранилище репозиториев, issue tracker, wiki и много-много еще чего полезного...
Если у вас уже есть репозитории, которые не плохо было бы отдать команде, не беда - можно перенести их в аккаунт команды за несколько кликов в панели управления.
Членам команды могут быть назначены разные уровни доступа. Для деплоймента теперь можно создавать отдельные ssh-ключи, которым будет разрешен только pull.
Что тут скажешь? Глобализация. У разработчиков все меньше и меньше поводов обзаводится собственными серверами, а стартапы теперь можно начинать и вовсе без денежных вложений.

Примеры bitbucket'а на своем домене:


Тут можно создать команду: https://bitbucket.org/account/create-team/.

Подробней об этой и прочих фичах можно почитать по ссылке http://go-dvcs.atlassian.com/display/aod/Configuring+a+Bitbucket+account+for+your+team.

26 окт. 2012 г.

Джордж Карлин

Джордж Карлин - великолепный американский комик. Я очень люблю его выступление про новую парадигму "земля + пластик". Вообще, для него нет запретных тем. Уверен, когда-нибудь он шутил даже про женские усы (одна из тех вещей, которую все не замечают ;) ).
Когда у меня плохое настроение или не хватает мотивации делать что-либо, я просто открываю один из его концертов с ютуба.
Чтобы полюбить Карлина как люблю его я, нужно смотреть концерты в обратном хронологическом порядке. По аудиозаписям Джорджа здорово учиться английскому, но если  вас с этим проблемы, смотрите его в переводе и с титрами.
Я знал, что Карлин снимался в Догме, но не догадывался, что он еще и озвучивал Филмора в первой части Тачек и был уморным Зугором в диснеевском мультике Тарзан 2.
Кто-то называет Карлина - американским Задорновым, я не согласен. Задорнов конечно тоже показывал гибона, но все же Карлин намного жестче.

18 окт. 2012 г.

Pattern для любого датамайнинга на python

Речь сегодня пойдет о Pattern - модуле-комбаине для датамайнинга по разным "стихиям" (web, db, text analysis и пр.).
Самый, ожидаемо-популярный в Pattern пакет, как мне кажется, - web (документация). Он умеет возвращать, например, результаты поиска по поисковым системам Google, Bing, Yahoo. Также умеет искать в Twitter и Flickr.
Библиотека очень объемная, в том числе и потом, что включает некоторые другие библиотеки удобно используемые для решения задач Pattern'а.
В научной работе выделяют 2 взгляда на пользу научных изысканий: изобретение нового и обощения опыта в уже открытом. Программисты традиционно стремятся изобретать все с нуля, поэтому любой пакет обединяющий старый признанный опыт как глоток свежего воздуха.

Tears of Steel - Blender Foundation's fourth short Open Movie

Увидел в блоге у vasnake. Сделано очень здорово.

27 сент. 2012 г.

Ужасная история

Одному прекрасному человеку нравились эти стихи. Так вышло, что этого человека больше нет...

Принцесса и людоед (или все наоборот)

Вот как это было.

Погода была ужасная,
Принцесса была прекрасная.
Днем во втором часу
Заблудилась принцесса в лесу.

Смотрит: полянка прекрасная,
На полянке землянка ужасная,
А в землянке людоед:
- Заходи-ка на обед.

Он хватает нож, дело ясное,
Вдруг увидел какая прекрасная...

Людоеду сразу стало худо.
- Уходи, - говорит, -отсюда.
Аппетит, - говорит, -ужасный,
Слишком вид,-говорит,-прекрасный.

И пошла потихоньку принцесса,
Прямо к замку вышла из леса.
Вот какая легенда ужасная,
Вот какая принцесса прекрасная.

А может все было наоборот?..

25 июл. 2012 г.

Продам платформу для создания видео-хостинга

Продам комплексной решение для создания видео-хостинга с UGC, конвертацией файлов, продажей полных версий роликов, интеграцией с социальными сетями, поддержкой HTML5 (если веб-клиент умеет), онлайн-вещание, плагины и др. пр. Цена - жалкие 150 тысяч рублей. Доделка под покупателя в стоимость не входит.
Раннюю-раннюю версию можно посмотреть по адресу http://www.russned.tv/.
Пишите markeev@gmail.com, звоните +79266634080.

16 июл. 2012 г.

Рефлекция

В детстве ищешь поддержки у мифических сущностей. Надеешься, что кто-нибудь даст тебе супер способности, из-за того, что ты такой уникальный и вообще один такой на свете. С возрастом понимаешь, что все настоящие боги работают в соседнем офисе, и они тебе, в плане развития и самосовершенствования могут дать намного больше, чем бородатый мужик сидящий на облаках.

ЗЫ. "Соседний офис" тут для красного словца. У меня через стенку сейчас комната охраны, у этих высоко интеллектуально развитых людей тоже наверное можно чему-нибудь научиться, но я ещё не дошел до такого высокого уровня рефлексии.


ЗЫ2. Рефлексия - обращение внимания субъекта на самого себя. В связи с этим новый термин: рефлекция (не путать с эрекцией) - способность субъекта к самопознанию.

12 июл. 2012 г.

Redmine

Так уж вышло, что redmine - своеобразный стандарт в области веб-разработки, при том, на мой взгляд, он абсолютно не юзабелен. Каждый раз, в новом коллективе я вынужден объяснять как пользоваться редмайном правильно, так же как и мне в свое время объясняли это в Deluxe Interactive. Как известно, можно даже зайца научить курить, но зачем? Хуже redmine только trac.
Каждая попытка найти годную альтернативу redmine заканчивается дилеммой вида "стоит ли платить за очередное ЭТО 10$/20$/200$ в день/месяц/год или за голову программиста". Практика продавать saas "в одни руки" для подобных систем вряд ли окупается, но невероятно распространена... Как дальше жить?

11 июл. 2012 г.

MaxMind GeoIP и GeoIPCity на ур-не nginx


Далее заметка в духе "написал, чтоб не забыть"... Хотя, забывать то особо нечего.

Под GeoIP принято понимать набор программных инструментов, позволяющих определить географическое положение клиента по его IP адресу.
Во-первых, у MaxMind есть несколько видов GeoIP баз. В общем случае они делятся на базы со странами и базы с городами. В базах со странами городов нет ), в базах с городам есть не только города но и всякие там metro коды (отдельная ветка баз).



Эти БД нужны, например, для фильтрации трафика по странам, отключению лицензионного контента в России, например, и пр. Для точного таргетинга бесплатные базы без городов, например, не подходят.
В базах по городам данных, например, больше, такие базы чуть тяжелее.

Есть бесплатные и платные версии баз maxmind. Удивительно, но факт - в платных версиях больше данных, например, и они точней, например.


http://youtu.be/UJkvjC17epQ.



Установка бесплатной базы maxmind с данными о городах

1. Настраиваем nginx

sudo vim /etc/nginx/nginx.conf

http {
    geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
    ...

2. В fastcgi_params добавляем

sudo vim /etc/nginx/fastcgi_params

### SET FASTCGI Variables ###
fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
fastcgi_param GEOIP_REGION $geoip_region;
fastcgi_param GEOIP_CITY $geoip_city;
fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code;
fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
fastcgi_param GEOIP_LATITUDE $geoip_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip_longitude;

для uwsgi соответственно 

sudo vim /etc/nginx/uwsgi_params

### SET UWSGI Variables ###
uwsgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;

3. Качаем лайт базу (безвозмездно, значит даром)

wget -c http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

gunzip GeoLiteCity.dat.gz

куда-нибудь в /usr/local/share/GeoIP/

4. Ставим пакеты - не знаю, когда это нужно, т.к. у меня на убунте и федоре уже стояли.

sudo apt-get install geoip-bin libgeoip-dev libgeoip1

5. Перезапускам nginx

6. Теперь можно использовать переданные модулем nginx заголовки:

GEOIP_CITY
GEOIP_CITY_CONTINENT_CODE
GEOIP_CITY_COUNTRY_CODE
GEOIP_CITY_COUNTRY_CODE3
GEOIP_CITY_COUNTRY_NAME
GEOIP_LATITUDE
GEOIP_LONGITUDE
GEOIP_POSTAL_CODE
GEOIP_REGION

Вот пример данных из лайт базы для моего рабочего IP
'GEOIP_CITY': '',
'GEOIP_CITY_CONTINENT_CODE': 'EU',
'GEOIP_CITY_COUNTRY_CODE': 'RU',
'GEOIP_CITY_COUNTRY_CODE3': 'RUS',
'GEOIP_CITY_COUNTRY_NAME': 'Russian Federation',
'GEOIP_LATITUDE': '60.0000',
'GEOIP_LONGITUDE': '100.0000',
'GEOIP_POSTAL_CODE': '',
'GEOIP_REGION': ''

Не очень точно, да?

Использование платных версий Maxmind ДБ

Для загрузки баз воспользуйся логопасом, у вас ведь есть подписка MaxMind? http://www.maxmind.com/app/account. Загрузить БД можно по адресу: http://www.maxmind.com/app/download_files. Думаю, опытный пират найдет способ скачать платную версию MaxMind с rutracker.org, но я ни коим образом не поощряю подобное поведение ;).

1. GeoIP Country binary database - база данных стран

http {
    geoip_country GeoIP.dat;
    ...

Доступные параметры:

fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3;
fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;

2. GeoIP City binary database - база данных городов

http {
    geoip_city /usr/local/share/GeoIP/GeoIPCity.dat;
    ...

Пример ответа для того же IP
'GEOIP_CITY': 'Moscow',
'GEOIP_CITY_CONTINENT_CODE': 'EU',
'GEOIP_CITY_COUNTRY_CODE': 'RU',
'GEOIP_CITY_COUNTRY_CODE3': 'RUS',
'GEOIP_CITY_COUNTRY_NAME': 'Russian Federation',
'GEOIP_LATITUDE': '55.7522',
'GEOIP_LONGITUDE': '37.6156',
'GEOIP_POSTAL_CODE': '',
'GEOIP_REGION': '48'

Чуть точней, но все равно "та же х**ня, Миша".

Можно использовать обе базы (country и city) одновременно, но особого смысла в этом нет ).

см. http://wiki.nginx.org/HttpGeoipModule или http://nginx.org/ru/docs/http/ngx_http_geoip_module.html#geoip_country

Важный момент: есть подозрения, что мобильный трафик льется через крупные города, так что если вы планируете фильтровать трафик из российской глубинки - вас ждет разочарование.

Очевидное наблюдение: MaxMind БД для использования в больших международных проектах с не очень высокой точностью геотаргетирования.

При платной подписке вам дают возможность скачать все данные из базы в формате CSV. В нашем проекте эти данные используются для установки параметров таргетирования баннеров клиентами через соответствующую панель на сайте.

Альфа.Клик и кредиты

"Десять тысяч ли за спиной, — подумал Степа. — А грабли все те же."


Дорогой Альфа банк, почему авторизации по паролю и смс тебе достаточно для того, чтобы позволять знающему паролю и заполучившему телефон человеку распоряжаться деньгами на всех счетах клиента, но мало для того, чтобы дать клиенту кредит? Неужели потому, что важная часть работы кредитного-менеджера это обман будущего клиента?

Не может же быть, что бы условия кредита предоставленные в наглядном печатном виде без ссылок и сносок убедили человека не брать кредит. Ведь кредиты в нашей стране берут по совсем другой причине. Мозг обывателя жаждет наслаждения прямо сейчас, сию секунду. Ждать мочи нет! Поэтому, когда человек приходит к кредитному консультанту он, на самом деле, для себя уже все давно решил. Цифры и числа написанные в договоре не окажут особого влияния на его выбор, а вот не профессиональный консультант может оказать такое влияние. Не говоря уже о том, что среди этих персонажей попадается не малое количество мошенников, жаждущих утянуть у банка деньги по несуществующим паспортам...

Я с легкостью представляю, как в Альфа.Клике появляется раздел "взять кредит", в котором все тот же человек, с логином, паролем и телефоном заполняет анкету и получает после проверки и одобрения кредитный счет, на который можно будет осуществлять переводы со своего текущего счета (лишний пластик не нужен, его и так слишком много). Деньги данные банком в кредит для простоты можно перевести на текущий счет. В чем могут быть сложности при реализации такой схемы?

19 апр. 2012 г.

Парсинг позиций в выдаче google и яндекс на python / grab

Ниже грубый, но работающий код парсинга результатов поисковой выдачи с использование python, grab. Здорово, что pyquery запросы к DOM можно выполнять прямо из grab объекта.
from grab import Grab
from django.utils.http import urlquote_plus




def google_position(query, url, start=False):
    if start > 240:  # 10 * 24
        return None
    google_url = 'http://www.google.com/search?q=%s' % urlquote_plus(query)
    if start:
        google_url += '&start=%d' % start
    g = Grab()
    g.go(google_url)
    for i, r in enumerate(g.pyquery('li.g cite')):
        if url in r.text_content():
            if start:
                return start + i + 1
            return i + 1
    if start:
        return google_position(query, url, start=start + 10)
    return google_position(query, url, start=10)

def yandex_position(query, url, page=False):
    if page > 24:
        return None
    yandex_url = 'http://yandex.ru/yandsearch?text=%s' % urlquote_plus(query)
    if page:
        yandex_url += '?p=%d' % page
    g = Grab()
    g.go(yandex_url)
    for i, r in enumerate(g.pyquery('.b-body-items .b-serp-item__title-link')):
        if url in r.get('href'):
            if page:
                return page * 20 - 10 + i + 1
            return i + 1
    if page:
        return yandex_position(query, url, page=page + 1)
    return yandex_position(query, url, page=1)

8 апр. 2012 г.

Второй Moscow Django Meetup

Засветился на фотках в отчете Future Colors http://blog.futurecolors.ru/2012/04/moscow-django-meetup-2.html.
Первая - самая ржачная (фото твиттер ленты с экрана). На встрече было дико душно, т.к. в аудитории было дофига народу. Мы сидели почти в конце аудитории в дальней от окон части. 70 мужиков выдышали весь воздух к концу первого доклада, а твиттер никто из организаторов не читал :). Мне пришлось помимо вежлевого твита ещё голосом попросить открыть окно.

28 мар. 2012 г.

16 мар. 2012 г.

Благодарность

Активно ищу работу через социальные сети. Обнаружил, что в МоемКруге есть несколько рекомендации этого блога. Спасибо этим прекрасным людям: http://moikrug.ru/circles/530265091/.

2 мар. 2012 г.

Python virtualenv on mac os

Да, я купил mac и теперь буду писать в блоге о том, что все уже давным-давно прошли. Грабля номер раз, на которую я наступил:


$ virtualenv myenvfor27
New python executable in myenvfor27/bin/python
Error [Errno 2] No such file or directory while executing command install_name_tool -change /System/Library/Fram.../Versions/2.7/Python @executable_path/../.Python myenvfor27/bin/python
Could not call install_name_tool -- you must have Apple's development tools installed
Traceback (most recent call last):
  File "/usr/local/bin/virtualenv", line 8, in <module>
    load_entry_point('virtualenv==1.7.1.2', 'console_scripts', 'virtualenv')()
  File "/Library/Python/2.7/site-packages/virtualenv-1.7.1.2-py2.7.egg/virtualenv.py", line 928, in main
    never_download=options.never_download)
  File "/Library/Python/2.7/site-packages/virtualenv-1.7.1.2-py2.7.egg/virtualenv.py", line 1029, in create_environment
    site_packages=site_packages, clear=clear))
  File "/Library/Python/2.7/site-packages/virtualenv-1.7.1.2-py2.7.egg/virtualenv.py", line 1347, in install_python
    py_executable])
  File "/Library/Python/2.7/site-packages/virtualenv-1.7.1.2-py2.7.egg/virtualenv.py", line 966, in call_subprocess
    cwd=cwd, env=env)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 672, in __init__
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1202, in _execute_child
OSError: [Errno 2] No such file or directory

install_name_tool входит в Command Line Tools из Xcode. Чтоб заработало нужно:
1. Поставить Xcode через App Store
2. Зайти в системное меню Xcode->Prefences->Downloads
3. Нажать кнопку инсталл напротив Command Line Tools, убить 10 минут на регистрацию в developer.apple.com (мне пришлось заполнять пункт "компания" всякой ерундой, т.к. в данную секунду я не отношусь ни к компаниям, ни к университетам).

28 февр. 2012 г.

Парсинг сайтов на python

Привет, друзья!
Нужен ваш профессиональный совет: чем современный питонист должен парсить сайты?
Поводом для обращения к аудитории для меня послужило открытие либы pyquery, которая позволяет делать jqurey-style  запросы по xml-документам. Я вдруг осознал, что есть много нетрадиционных, но весьма удобных подходов к проблемме.
А какие интересные и удобные способы парсинга известны вам?

14 февр. 2012 г.

Ekbpy видео

http://video.yandex.ru/#search?text=ekbpy (почему-то, у меня каждое видео по 2 раза в списке).

Я успел побывать на докладах:
  1. ZeroMQ. Intro.
  2. Системное программирование в Linux на питоне.
  3. Питомник: фреймворк для разработки распределенных сервисов. 
  4. Python 3: фичи и проблемы портирования.
  5. Celery для веб-сервисов. Асинхронное распределенное выполнение задач.
Оказывается, kmike играет на бас-гитаре в банде АлоэВера (пруф).

Ещё разок здесь напишу: конференция была организована великолепно. Не успевал я подумать о том, что не хило было бы выпить кофе - услужливые ребята вкатывали столики с кофе, чаем и бутербродами. Накладок не было вообще никаких. Мы вышли на обед перед мастер-классом по celery, а когда вернулись, аудитория со стульями превратилась в аудиторию с партами.
Открытый бесплатный wifi, розетки для ноутов - все по взрослому.
Огромное спасибо организаторам, надеюсь такие конференции будут регулярными.

UPD. Пара моих фоток с конференции:

















3 февр. 2012 г.

Едем на ekb.py

10го февраля группой единомышленников едем на http://www.ekbpy.ru/ (Конференция для настоящих и будущих разработчиков на Python). Участие в коференции платное - 1500 рублей.

Тюменцы, все кому не безразличен питон и приятна хорошая компания, милости просим с нами!
Едем на машинке. В машинке из 5 мест, свободны пока 2. Если народу наберется много, едем на двух машинках. Места при таком раскладе в два раза больше ;).

Пока партийный список такой:
Я, Дима Scailer и Андрей З.

Думаю, мы найдем способ скинутся на бензин. Возьмем с собой в дорогу какую-нибудь еду. Я и Андрей идем на мастер-класс для опытных, который ведут Антон Патрушев (Naumen), Роман Иманкулов (NetAngels), Илья Шабалин (Exadel). Очень хотелось послушать Мишу Коробова по больше (его доклад есть в основоной программе конференции), но 3ий питон пока не очень востребован в наших широтах.

UPD. Точно на двух машинах едем, т.к. добавились ещё 3 пассажира: Иван Ш., Сашка и моя мама (тоже едет в Екб, оказывается, в этот же день. Позвоните родителям! :) ). Ещё 2-4 места в машинах вакантны. Милости просим!

UPD. Добавились ещё двое - Илья и Ильнур.