Пример веб-скрапинга ВК-API на языке Python

Вы никогда не думали над тем насколько ценным ресурсом могут быть социальные сети, когда речь заходит о социологических и психологических исследованиях? Только подумайте сотни тысяч людей, которые выкладывают о себе информацию в электронном виде. Только возьми, разпарси, обработай эти данные и ценные крупицы знания о человеческом поведении у тебя в кармане (иллюминаты, читающие блог, вам привет 🙂 △ ). А если серьезно, конечно, никакой сложной информации таким методом получить не выйдет, но определенную статистику вполне получить можно…

Так вот, вас никогда не интересовала статистика того какой процент пользователей вк скрывают свой возраст на страничке, и какое соотношение мужчин и женщин среди них. Честно, меня не особо. Но больно захотелось применить Python на чем-то более менее полезном, и тогда была придумана эта немного искусственная задача. Зато вполне соответствующая области применения питона.

Вообщем, после создание своего приложения на странице ВК для разработчиков, перед вами открывается безграничные возможности для сбора статистики общедоступных данных из вк.

После этого был написан вот такой скрипт:

import urllib.request
import json

startId = #тут id с которого начинается скан
i = 0
count = 2000000
countInOneRequest = 200
token = '' # тут  токен вашего приложения



allMale = 0
allFemale = 0
withBDateMale = 0
withBDateFemale = 0
withAgeMale = 0
withAgeFemale = 0

while i < count:

    current = i+startId
    url ='https://api.vk.com/method/users.get?user_ids='
    while current <= i+startId+countInOneRequest:
        url += str(current)+','
        current+=1
    url = url[0:len(url)-1]
    url += '&fields=bdate,sex&access_token=' + token + '&v=V '
    print(url)
    response = urllib.request.urlopen(url)

    for elem in json.loads(response.read())['response']:
        #print(elem)
        if elem['first_name']!='DELETED':

            if elem['sex'] == 1:
                if 'bdate' in elem:
                    withBDateFemale+=1
                    if elem['bdate'].count('.')==2:
                        withAgeFemale+=1
                allFemale += 1
            if elem['sex'] ==2:
                if 'bdate' in elem:
                    withBDateMale+=1
                    if elem['bdate'].count('.') == 2:
                        withAgeMale+=1
                allMale += 1
    i +=countInOneRequest+1
    print('Current '+str(i)+' '+' / '+str(count))
    print('All Male: ' + str(allMale))
    print('With Birth Day :' + str(withBDateMale))
    print('With Age:' + str(withAgeMale))
    print('All Female: ' + str(allFemale))
    print('With Birth Day :' + str(withBDateFemale))
    print('With Age:' + str(withAgeFemale))

print('END')
print('All Male: ' + str(allMale))
print('With Birth Day :' + str(withBDateMale))
print('With Age:' + str(withAgeMale))


print('All Female: ' + str(allFemale))
print('With Birth Day :' + str(withBDateFemale))
print('With Age:' + str(withAgeFemale))

Вообщем принцип действия прост:

  1. Отправляем get-запрос методу который возвращает информацию о пользователях, при этом формируем запрос сразу на 200 пользователей (так реально быстрее).
  2. Парсим полученный json в пайтоновский set и итерируемся по каждому элементу
  3. Проверяем что пользователь не является удаленным
  4. Если не удален, смотрим на пол пользователя и переходим по соответствующему условному блоку.
  5. В этом условно блоке смотрим вернулась ли информация с сервера о дате рождения пользователя, если да то в каком виде ( с годом рождения или без).
  6. Увеличиваем соответствующие счетчики.

Вообщем скрипт проработал у меня примерно час, и за это время он собрал информацию о 2 миллионах пользователях. Вот результат:

В целом оказалось что женщины чаще ставят дату рождения (21 % среди мужчин против почти 24% женщин). Однако полную дату рождения с годом мужчины ставят чаще чем женщины (12,4 % среди мужчин против 11% женщин). Оно и понятно: мужчины более скрытны по своей природе, однако если решил поставить дату то и год скрывать нечего. А о возрасте дамы говорить не культурно, поэтому дамы готовы делится информацией о дне рождения, но не о своем возрасте.

Вот таким нехитрым образом можно парсить сайты и собирать всякую инфу)) Спасибо за внимание!

Как PHP из шаблонизатора превратился в полноценный язык и к чему это привело?

Думаю, что ни для кого не секрет, что PHP изначально не задумывался как полноценный язык программирования. Он был скорее web-фреймворком для Perl, который позволил своему создателю Расмусу Лердорфу быстро сделать интернет-страницу для своего резюме в обеденный перерыв в 1994 году. Это было довольно дремучее время, когда в интернете не было котиков и хипстеров (да что там, Гугла с Яндексом тоже не было!). Трудно представить, но многие в то время писали для web на C и типичный код обработки запроса мог выглядеть так:

#include <stdio.h>;
#include <stdlib.h>;
int main(void) {
// Извлекаем значения переменных окружения
char *remote_addr = getenv("REMOTE_ADDR");
char *content_length = getenv("CONTENT_LENGTH");
char *query_string = getenv("QUERY_STRING");
// Вычисляем длину данных - переводим строку в число
int num_bytes = atoi(content_length);
// Выделяем в свободной памяти буфер нужного размера
char *data = (char *)malloc(num_bytes + 1);
// Читаем данные из стандартного потока ввода
fread(data, 1, num_bytes, stdin);
// Добавляем нулевой код в конец строки
// (в C нулевой код сигнализирует о конце строки)
data[num_bytes] = 0;
// Выводим заголовок
printf("Content-type: text/html\n\n");
// Выводим документ
printf("");
printf("");
printf("");
printf("");
printf("");
printf("");
printf("");
printf("Здравствуйте. Мы знаем о Вас все!");
printf("Ваш IP-адрес: %s", remote_addr);
printf("Количество байтов данных: %d", num_bytes);
printf("Вот параметры, которые Вы указали: %s", data);
printf("А вот то, что мы получили через URL: %s", query_string);
printf("");
}

И все бы ничего, но вот проблема: все существующие тогда решения для web-разработки заставляли делать очень много рутинных шагов, и заставляли программиста сосредотачиваться не на своей прикладной задаче, а на том как не наделать ошибок при обработке, например строк в HTTP запросах (посмотрите еще раз как мучительно это делалось на C). Так вот, Расмусу это надоело, и он автоматизировал многие рутинные действия, возникающие перед веб-разработчиком в PHP.  Даже первая версия языка была уже не плоха для своего времени, учитывая то, что приходилось делать на C. PHP уже обладал всеми свойствами полноценного языка программирования (был Тьюринг полным), поддерживал переменные, циклы, пользовательские функции. Но что гораздо важнее, он позволял мыслить разработчику в контексте web-разработки. Например, получать и устанавливать cookie, обрабатывать параметры HTTP запросов. И все это в одну строчку кода.  Конечно, он был удобнее, чем большинство средств того времени. И как часто это бывает в IT, удобный инструмент для личного пользования быстро становится достоянием общественности. Не обошла эта участь и PHP. А затем, как неизбежно случается, люди, получив в руки крутой инструмент, начали просить о большем количестве возможностей. И тут началось, пожалуй, самое интересное…

Программа для компьютера, как и любой другой объект технического творчества человека,  подразумевает, что отдельные ее части будут минимально работоспособны и независимы друг от друга.  Например, мы можем поставить двигатель машины в другую машину с похожими параметрами, и она должна завестись и поехать, а если не заведется – это признак плохого дизайна. В программной инженерии точно также. Например, мы делаем приложение, которое показывает нам список лучших фильмов, при этом использует базу данных либо Кинопоиска, либо IMDB. В случае если мы сумеем оформить обращения к базам данных в виде отдельных программных модулей, при замене одного компонента на другой, у нас не должно ничего поломаться в программе. А если поломалось, то это признак плохого дизайна… Так вот, это присказка…

PHP, в связи с его растущей популярностью, начал развиваться именно в сторону модульности. Причем в двух направлениях: на уровне модулей подключаемых к интерпретатору, и на уровне пользовательского кода, т.е. добавление возможностей в язык ООП. И вправду первый код, который писали на языке мог выглядеть так:

<head>
 <title>Гарантированный прием значений от флажков</title>
 <meta charset='utf-8'>
</head>
<body>
 <?php if (isset($_REQUEST['doGo'])) { foreach ($_REQUEST['known'] as $k=>$v) {
 if($v) echo "Вы знаете язык $k!";
 else echo "Вы не знаете языка $k.";
 }
}
 ?>
 


<form action="<?=$_SERVER['SCRIPT_NAME']?>" method="post">
 Какие языки программирования вы знаете?
 <input type="hidden" name="known[PHP]" value="0">
 <input type="checkbox" name="known[PHP]" value="1">PHP
 <input type="hidden" name="known[Perl]" value="0">
 <input type="checkbox" name="known[Perl]" value="1">Perl
 <input type="submit" name="doGo" value="Go!">
 </form>



</body>
</html>

И этот код ужасен… И вот почему: в рамках одной программной единицы, мы одновременно занимаемся обработкой HTTP запросов, программируем логику приложения, и выдаем представление (работаем с графическим интерфейсом). Т.е. в рамках парадигмы архитектурного шаблона MVC, в одном файле model, view и controller. Это плохо потому, что в случае если надо поменять верстку, мы случайно можем поменять код, который отвечает за логику, потому что нет четких границ ответственности при таком проектировании. Как говорит известный архитектор ПО Роберт Мартин про такой дизайн: “Программист борется с ветряными мельницами, а не пишет код”. Это абсолютно не приемлемо, если мы хотим писать большое web-приложение типа Facebook или Vk (хотя такой код до сих пор будет работать в интерпретаторе PHP). Именно поэтому, дальнейшие разработки PHP шли в направлении добавления возможностей ООП. Кстати, самыми модными и крутыми тогда были именно ООП языки. Да и об языке, который поддерживает ООП уже нельзя говорить как о просто шаблонизаторе. Это полноценный язык, на котором можно писать сколь угодно сложные приложения и не запутаться в каком месте и что происходит. Поэтому современный PHP как бы его не хаяли за его прошлое, на самом деле очень крут именно благодаря ООП, и не хуже Джав и Питонов для web. Конечно, если мы говорим о написании сайтов и веб-приложений (например, API для мобильного приложения дублирующее функционал сайта). Если же мы пишем высоконагруженный сервер для онлайн игры, используя сокеты, то лучше смотреть в сторону Java или Go…

Ну а дальше появились всякие Laravel’ы, Symphony, Yii… Т.е. фреймворки, которые довели идею модульности и ООП дизайна до абсолюта, избавив программиста от головной боли думать о хорошем дизайне, предоставили ему каркас-скелет, на который он уже может наращивать свой предметный функционал.

Спасибо, если дочитали до конца 😉

Почему разработка сложного web-приложения крайне желательна с использованием IDE и локальной приложения копии?

Иными словами это статья на тему “Почему все надо делать по-человечески, особенно когда речь идет о разработке ПО?”(Шутка). Вообщем, это скорее даже моя жизненная история, касающаяся удобства при web-разработке. А в конце как всегда немножко глубокой философии. Всем сомневающимся посвящается.

Когда я только начинал работать web разработчиком в одной сайтостроительной студии, меня старались убедить в том, что фигачить код сразу на продакшн сервер, используя девелоперский поддомен это нормально. С осознанием этой мысли, вбитой мне в голову, я жил, пописывая помаленьку всякие web штуки для своих нужд. Пока однажды, моя дурная голова (та самая, что рукам покоя не дает) придумала интересную идею клиент-серверного приложения (ну или мне просто кажется, что оно интересное… хотя об, может быть, в другой раз). Разрабатывать было решено на фреймворке Laravel. Ну и естественно поначалу я начал фигачить как меня учили, закидывая файлики по FTP . Но столкнулся сразу с очень большим количеством проблем. Например, в Laravel очень многие вещи делаются через интерфейс командной строки – Artisan. И делать эти вещи по SSH не имея визуального представления о том, что происходит в структуре проекта как-то не очень удобно(какие файлы создаются и куда закидываются). Продолжать работу так я не хотел. Поэтому поставил интерпретатор PHP, сервер Apache с MySql себе на локальную машину. Чуть позже на моем рабочем столе появился ярлык одной популярной IDE… Дальше обещанная философия.

Отложим все частности и поговорим в целом, почему это удобно когда вы работаете с локальной копией:

  1. Вы визуально видите иерархию папок и файлов в вашем проекте, можете быстро переключаться между ними. В отличии от консольного интерфейса SSH где вам придется вводит много рутинных команд, чтобы сделать простое действие(да простят меня олдскульные фанаты консоли).

    Вроде одно и то же. Просмотр иерархии файлов проекта. Но в случае с консольным интерфейсом пришлось “попотеть” – ввести пару-тройку команд. Во втором случае просто кликнуть мышью.
  2. Вы не тратите время на закидывание файлом по FTP/SSH( А ведь бывают еще ситуации(редко) когда сервер отвалился или интернет упал…). Тратьте время на действительно важные вещи, например на продумывание архитектуры приложения, или алгоритма, который лучше подойдет в данном случае. Посему, работаете у себя на локалке, а потом развертываете приложение, когда оно готово при помощи Git или того же SSH.
  3. Подсказки со стороны IDE. Все что касается всплывающих названий методов и классов, подписанных названий параметров функции и т.д. Это бывает очень удобно. Особенно когда давно работал над проектом и уже не помнишь как и что называлось у тебя полгода назад. В отличии от IDE продвинутые текстовые редакторы(такие как Notepad++) могут напомнить название метода, только в рамкам одного файла.
    Это всплывающая подсказка, касающаяся класса, который находится в другом файле и в другой папке. Лезть туда и смотреть названия всех этих методов было бы долго.

 

Я думаю, очевидно, что время которое вы потратите на развертывание локального окружения окупиться очень быстро. И вы будите тратить меньше умственных ресурсов вспоминая, как называлась функция, которая делала задачу N в классе M. Поверьте, это очень спасает. IDE как всегда автоматизирует многие процессы, помогает избежать рутинных действий.

Вообщем, вы поняли посыл. Будьте человеком.

Почему архитектурный шаблон проектирования MVC хорош, и когда его стоит применять?

Coming soon ;))

Сертификация Mail.ru – Java

У меня довольно скептическое отношение к сертификациям для программистов, поскольку способность решать тесты не отражает реальной способности писать хороший код (эффективный и читабельный).

Однако для закрепления и устранения пробелов в знаниях конкретных ЯП они вполне подходят. Поэтому прошел сертификацию Mail.ru по Java (https://certification.mail.ru). Буду пробовать улучшить результат. https://certification.mail.ru/certificates/6b63950c-76fc-485d-9979-b04c68bbabad/

Визуализатор точек на карте

Однажды в универе нам дали такое задание на практику: разбить точки производства кластеры при помощи готовых программ. Вообщем-то ничего интересного, нажми на кнопку – получишь результат. Но была в этом задании одна интересная часть которую я с радостью взял на себя, отправив парней из моей подгруппы заниматься освоением программы для статистического анализа Statistica. Так вот, эта часть заключалась в том, что нужно было визуализировать эти кластеры на карте. Готовых программных решений не нашел (быть может плохо искал). И решил написать свое web-app для визуализации на основе api Яндекс Карт. Быть может поможет кому-нибудь красиво оформить учебную работу. Далее привожу описание и ссылку на github.

Получилось “няшно”

P.S. Для тех кто не шарит во всем этом программировании: качаете файл html, который есть в git репозитории. Открываете его в браузере, делательно Chrome-в других не тестил. И пишите описание ваших точек в формате json в текстовое поле (пример json структуры есть под картой). Далее нажимаете кнопку “визуализировать” и ваши точки появляются на карте. Для того чтобы автоматизировать описание точек если их много есть веб-сервис, которые может вашу excel таблице преобразовать в json структуру – https://codebeautify.org/excel-to-json

Ссылка на github репозиторий

https://github.com/GurSergey/YandexMapsVisualizer

Описание к использованию

Приложение представляет из себя web-страницу с картой и текстовым полем в котором описываются географические точки в формате json. Структура, описывающая географическую точку, содержит координаты, вес точки (размер), кластер к которому она принадлежит (точки одного кластера имеют один и тот же цвет; цвет генерируется случайным образом). Тип геометрической фигуры (возможные варианты circle-окружность, square-квадрат, polygonN-правильный многоугольник, вписанный в окружность, где вместо N подставить количество углов многоугольника).