前些天做销售的同事给我出了个题目: 她的客户数据里有很多的 Email 地址都是过期的或者错误的, 因此群发发邮件时会收到很多退信. 但是由于数量较大, 又不好手工去一一找出哪些地址是无效的. 有没有可能用程序解决呢?
当然是可能的啦, 思路: 首先肯定不能通过发邮件来测试, 因为, 乱发垃圾邮件那是违法的. 于是我采取三个步骤:
- 利用 regex 从 Email 地址的格式上先淘汰一些, 例如连 @ 都没有的那肯定不是合格的 Email 地址.
- 再从 DNS MX 记录上淘汰一些. 如果某域名没有有效的 MX 记录, 那该域名结尾的任何 Email 地址都是无效的.
- 最后使用 SMTP 协议”假装”发邮件, 只查询收件人是否存在, 便挂断.
基本能够达到目的, 但不保证 100% 准确. 因为… 很多发垃圾邮件的专业户也是这么做的, 所以一些邮件服务器对此是提防的. 程序如下.
require 'net/smtp' require 'dnsruby' class EmailValidator def check_format(email) m = /^[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.[A-Za-z]{2,4})$/.match email if m @domain = m[1] @email = email else puts "Invalid Email address for '#{email}'." return false end end def mx_lookup res = Dnsruby::Resolver.new ret = res.query(@domain, Dnsruby::Types.mx) return ret.answer[0].exchange.to_s if ret && ret.answer && ret.answer[0] end def validate(email) return false unless check_format(email) mx = mx_lookup() if mx Net::SMTP.start(mx, 25) do |smtp| smtp.helo 'the.domain.name' smtp.mailfrom 'sender.email.address' smtp.rcptto @email smtp.finish end puts "Account exists for '#{@email}'." return true else puts "No MX available for '#{@domain}'." return false end rescue => err puts "Account may not exist for '#{@email}'." puts err return false end end
🙂
3 responses to “确认一个 Email 地址是否存在”
You design a small program for your company and decided to help them,you solving a big problems for them. You are so great! I envy you.
我们管这个叫数据清洗,使用的方法也差不多
我认为群发邮件就是这么个问题,无论是否垃圾,要是能让每个客户都感觉是在享受单独服务就更好了。