Проверка e-mail адресов на существование: yandex, gmail, mail.ru, mail.com и др.

Проверка e-mail адресов на существование: yandex, gmail, mail.ru, mail.com и др.

В первой части статьи Универсальный чекер e-mail почты на валидность. Часть 1. мы говорили о методе проверке почтовых адресов к которым у Вас есть доступ (по паре логин:пароль). Сегодня мы продолжим данную тему и расскажем, как проверить почту на существование с помощью ZennoPoster.

Мы рассмотрим с Вами 4 пункта (условно их 3):
1. Проверить синтаксис написания почтового адреса по формату.
2. Проверить существование домена.
3. Подключиться к SMTP серверу проверяемого ящика и совершить попытку отправки письма.
3.1 Проверить существование email адреса через почтовый сервис.

Зачем это нужно?

Отправляя письма на несуществующие почтовые адреса, ваши письма будут определены как «нежелательные», что повлечёт за собой санкции со стороны почтового хостинга — бóльшая часть писем будет автоматически отправляться в папку спам или отклоняться вовсе.

И именно для того чтобы предотвратить появления в Вашей базе невалидных email-адресов, необходимо провести вышеописанные проверки.

Синтаксическая проверка

Проверка существования email адреса начинается с соответствия стандартам написания, согласно RFC 5322.

Например, хорошие:

Плохие:

 

Это регулярное выражение для канонических адресов электронной почты:

^(?(")(".+?(?<!\\)"@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$

Проверка существования домена

После проверки синтаксиса почтового ящика, необходимо удостовериться, что домен адресата активен.

Нас интересует не столько статус домена, сколько наличие MX (mail exchanger) записей в DNS. которые указывают серверы, на которые нужно отправлять электронную почту, предназначенную для адресов в данном домене. Если они не прописаны, значит и проверяемый нами почтовый ящик не существует.

Данную проверку можно осуществить разными способами. Я поделюсь с Вами четырьмя:

  • С помощью библиотеки ARSoft.Tools.Net.Dns
  • Запрос к dns.google.com
  • Утилита dig
  • Утилита nslookup

(Шаблон с примерами будет в комплекте)

Я воспользуюсь 4-им способом, так он мне наиболее привычен.

Стандартный кубик запуска программ не позволяет сохранить результат выполнения в переменную, поэтому будем выполнять её через C# код:

var mx_srv = project.Variables["MAIL_SERVER"].Value;

var process = new System.Diagnostics.Process {
    StartInfo = new System.Diagnostics.ProcessStartInfo {
     UseShellExecute = false,
     CreateNoWindow = true,
     RedirectStandardError = true,
     RedirectStandardInput = true,
     RedirectStandardOutput = true,
     FileName = @"cmd.exe",
     WorkingDirectory = @"C:\Program Files\dig",
     Arguments = @"/c nslookup -type=mx "+mx_srv
     }
};
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Close();
process.Dispose();
return output;

Анализ ответа почтового сервера

Финальный шаг — подключаемся к SMTP серверу и имитируем отправку сообщения на проверяемый ящик. Если вернётся ответ 250 — ящик существует, 550 — к сожалению, такого адреса нет. Данный способ не является панацеей т.к. не все почтовые сервисы возвращают корректный ответ на данную команду, к ним относятся Mail Ru, Mail.com, Hotmail, Yahoo (о них мы поговорим отдельно, чуть ниже). Но с такими популярными службами, как Яндекс и Gmail проблем не возникает.

Итак, чтобы начать, необходимо подключиться к одному из почтовых серверов по 25 порту, которые хранятся у нас в списке «MX».

Далее мы говорим ему привет 🙂 с помощью команды:

HELO domain.com

Где второе — это название домена с которого Вы обращаетесь, может быть любым.

После чего мы посылаем команду:

MAIL FROM:<[email protected]>

Cообщая, от чего имени мы будем вести беседу, и завершаем последней строчкой:

RCPT TO:<[email protected]>

И вот здесь мы ждём ответ, 250 — good, 550 — bad.

Код выглядит следующим образом:

var list = project.Lists["MX"];
var logg = new StringBuilder();
string rcpt = project.Variables["email"].Value;
string exFromMail = string.Format(@"{0}@mail.com", project.Profile.NickName);

string mx_Server = System.Text.RegularExpressions.Regex.Replace(list[0], @"\.$", "");
project.SendInfoToLog("Взяли MX: "+mx_Server);
	
try {		
	//TcpClient SmtpServ = new TcpClient(mx_Server,25);
	var SmtpServ = new TcpClient();
	if (!SmtpServ.ConnectAsync(mx_Server, 25).Wait(7000)) {
		list.RemoveAt(0);
		project.SendWarningToLog("Connection timeout");
		return null;
	}
	string Data;
	byte[] szData;
	string CRLF = "\r\n";
	project.SendInfoToLog("Законектились");
	// Инициализация
	NetworkStream NetStrm = SmtpServ.GetStream();
	NetStrm.ReadTimeout = 7000;
	SmtpServ.Client.ReceiveTimeout = 7000;
	StreamReader  RdStrm= new StreamReader(SmtpServ.GetStream());
	logg.AppendLine(RdStrm.ReadLine());
	// Приветствуем сервер
	Data = "HELO mail.com" + CRLF;                
	szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
	NetStrm.Write(szData,0,szData.Length);
	logg.AppendLine(RdStrm.ReadLine());
	project.SendInfoToLog("EHLO");
	Data = string.Format("MAIL FROM: <{0}>{1}", exFromMail, CRLF);
	szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
	NetStrm.Write(szData,0,szData.Length);
	logg.AppendLine(RdStrm.ReadLine());
	// Указываем получателя (ящик которого мы и будем проверять)
	Data = "RCPT TO: <"+rcpt+">"+CRLF;
	szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
	NetStrm.Write(szData,0,szData.Length);
	logg.AppendLine(RdStrm.ReadLine());
	// quit from server SMTP
	Data = "QUIT"+ CRLF;
	szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());
	NetStrm.Write(szData,0,szData.Length);
	//LogList.Items.Add(RdStrm.ReadLine());
	//logg.AppendLine(RdStrm.ReadLine());
	// Закрываем соединение
	NetStrm.Close();
	RdStrm.Close();
	//logg.AppendLine("Close connection");
} catch(InvalidOperationException err) {
	logg.AppendLine("Error: "+ err.ToString());
}
list.RemoveAt(0);
return logg;

С этим разобрались, супер!

Когда способ через SMTP сервер не работает — проверяем существование E-mail адреса через почтовый сервис

Вернёмся к почтовым сервисам, где данная проверка через SMTP сервер не работает (Mail Ru, Mail.com, Hotmail, Yahoo). Как же быть в таком случае?

На сайте КАЖДОГО почтового сервиса есть возможность восстановления пароля и\или проверка занятности адреса при регистрации, этими способами на примере двух сайтов (mail.ru и mail.com) мы и воспользуемся.

Mail.Ru

Переходим на страницу восстановления пароля: https://e.mail.ru/password/restore/

Перед нами несложная форма — то, что нужно!

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

Введём заведомо несуществующий логин и посмотрим, в каком виде нам придёт ответ.

Ключевой запрос, который нам нужен: https://e.mail.ru/api/v1/user/password/restore

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

Остается только перенести необходимые аргументы в запрос: X-Requested-With, Referer, X-Request-Id; Последний мы сгенерируем с помощью кода:

project.Variables["guid"].Value = Guid.NewGuid().ToString();

Последний шаг — формирование данных, которые необходимо передать в POST запросе. Делаем также по примеру:

Меняем статичные данные на переменные: tab-time (unix время) и e-mail, предварительно обработав UrlEncode.

Отправляем запрос и получаем примерно такой ответ:

Строчка «not_exist» означает, что ящика не существует, по ней и будем проверять все остальные почтовые ящики.

Не так уж и сложно, не правда ли? 🙂

Если всё-таки у Вас возникли сложности — пишите в обсуждении данной темы на форуме.

Mail.com

Переходим на страницу восстановления пароля: https://password.mail.com/passwordrecovery/

К сожалению, данная форма нам не подходит из-за каптчи т.к. это сильно будет тормозить процесс.

Воспользуемся вторым способом — проверкой занятости никнейма через форму регистрации: https://service.mail.com/registration.html

Рядом с полем ввода никнейма есть кнопка для проверки его на занятость, по клику на которую вылетит соответствующее уведомление:

Если же E-mail существует, появится следующий текст: nickna[email protected] is not available, please choose one of the following

Отследим запросы. Ключевой запрос выглядит так:

Нужные куки так же получаем после первого GET запроса к странице и копируем дополнительные заголовки: Wicket-Ajax, Wicket-FocusedElementId: id20

Данные для отправки выглядят следующим образом: [email protected]&

Значение zXXXXXXXX является динамическим, поэтому его, как и почту, необходимо заменить на переменную.

Применим xPath выражение, чтобы его достать: «.//*/span[contains(@class, ‘EmailAddress’)]/input»

Данные, которые передаются в URL (после знака вопроса) также являются динамическими и хранятся в аргументе onclick того же поля, откуда мы забрали нужно zXXXXXX значение.

Готово!

Отправляем запрос, парсим текст оповещения и определяем, существует почта или нет.

Готовый шаблон Вы можете скачать в теме данной статьи, на форуме.

Обсудить на форуме

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *