Python爬虫干货之如何通过邮箱批量注册账号?

Python爬虫干货之如何通过邮箱批量注册账号?

1、需求

产品经理拿刀驾在程序员的脖子上,要求实现邮箱批量注册某网站账号。

2、思路

首先说一下思路,要实现我们批量注册这个目标我们需要提出以下问题:

  • 问题a :批量注册,如何获取大量邮箱账号?
  • 问题b:如何搭建自己的邮件服务器?

如果有自己的邮件服务器,那么大量的邮箱账号就可以自己生成了。所以解决问题b就是解决了问题a.所以我们开始搭建自己的邮件服务器。

3、邮件服务器的原理

如上图,举个实际的例子,alice在mail.alice.com这里注册了一个邮箱,然后它要向bob发送邮件,bob的邮箱在mail.bob.com注册。我们需要明白以下几个事实: - 1、SMTP协议最初设计得比较简单,只支持单向的”推“邮件,也就是发邮件 - 2、发邮件使用的协议是SMTP,管理和接收邮件使用的协议是POP3或者IMAP - 3、alice发给bob,是先通过SMTP协议将邮件投递给alice的邮件服务商的服务器,然后alice的邮件服务商的服务器再将alice的邮件通过SMTP协议投递给bob的邮件服务商的服务器

综上,明白邮件服务器的原理,我们就知道,我们要用Python代码实现的为图中的bob的邮件服务器支持SMTP协议就OK了(为什么?我们可以把alice当作我们批量注册的时候发送邮箱验证码的那一方,而bob就是我们接收验证码这一方,bob这一方我们就没必要真的去实现bob的邮箱客户端,只需要实现服务器就能收到邮件了)。

4、如何代码实现邮件服务器?

很简单我们利用Python内置的smtpd来实现。整个完整代码笔者已经完整测试通过,我们先放上最核心的部分,定义一个类InboxServer继承python内置的SMTPServer,示例代码如下:

import smtpd
class InboxServer(smtpd.SMTPServer, object):
    """Logging-enabled SMTPServer instance with handler support."""

    def __init__(self, handler, *args, **kwargs):
        super(InboxServer, self).__init__(*args, **kwargs)
        self._handler = handler

    def process_message(self, peer, mailfrom, rcpttos, data):
        log.info('Collating message from {0}'.format(mailfrom))
        subject = Parser().parsestr(data)['subject']
        log.debug(dict(to=rcpttos, sender=mailfrom, subject=subject, body=data))
        return self._handler(to=rcpttos, sender=mailfrom, subject=subject, body=data)

以上程序process_message为实际处理收到的邮件的消息,注意到类的初始化函数传入了一个handler参数,这个参数实际传入的是一个函数对象,我们可以自己定义一个函数,来决定我们自己如何处理收到的邮件内容。 我们再定义一个类Inbox,用来实例化InboxServer,以及编写启动邮件服务器的一些方法。

import asyncore
import argparse
from email.parser import Parser
import logging
log = logging.getLogger(__name__)
class Inbox(object):
    """A simple SMTP Inbox."""

    def __init__(self, port=None, address=None):
        self.port = port
        self.address = address
        self.collator = None

    def collate(self, collator):
        """Function decorator. Used to specify inbox handler."""
        self.collator = collator
        return collator

    def serve(self, port=None, address=None):
        """Serves the SMTP server on the given port and address."""
        port = port or self.port
        address = address or self.address

        log.info('Starting SMTP server at {0}:{1}'.format(address, port))

        server = InboxServer(self.collator, (address, port), None)

        try:
            asyncore.loop()
        except KeyboardInterrupt:
            log.info('Cleaning up')

    def dispatch(self):
        """Command-line dispatch."""
        parser = argparse.ArgumentParser(description='Run an Inbox server.')

        parser.add_argument('addr', metavar='addr',
                            type=str, help='addr to bind to')
        parser.add_argument('port', metavar='port',
                            type=int, help='port to bind to')

        args = parser.parse_args()

        self.serve(port=args.port, address=args.addr)

需要注意的是Inbox这个类里面collate实际是一个装饰器,目的是传入我自己定义的处理邮件的函数,也就是所谓的handler,dispatch为实际启动邮件服务器的方法。 以上类定义好了,我们定义自己的处理邮件的代码:

from mailserver.inbox import Inbox
import email
from .userstuff import do_stuff

inbox = Inbox()


@inbox.collate
def handle(to, sender, subject, body):
    b = email.message_from_string(body)
    do_stuff(b)


def main():
    inbox.dispatch()


if __name__ == '__main__':
    main()

以上先实例化Inbox类,然后通过collate装饰器,装饰我们自己定义的处理邮件的函数handle,以后每一个发送到本邮件服务器的邮件,都会经过handle进行处理,比如我们可以在里面打印出邮件内容,判断是谁发来的邮件,或者提取邮件里面的验证码,不一而足。 然后我们对代码进行打包,封装(完整的代码下载,请关注本公众号,在对话框发送“批量邮箱注册”,获取下载链接)。我们下载下来,进入mailserver执行:

python setup.py install

安装好包,最后启动邮件服务器,可以随意设置未使用的端口,我们设置监听25:

mailserver 0.0.0.0 25

5、配置邮件服务器

我们需要一台公网服务器,例如阿里云,按照前面的步骤,部署启动好,邮件服务器。 购买一个域名将其mx字段配置指向服务器公网ip。接下来就可以开始批量注册了,举个例子:

我们公网服务器ip为88.88.88.88,域名为test.com,我们配置mx记录指向test.com 那么邮箱目的地址只要是test.com结尾的,都会将邮件投递到我们88.88.88.88这台服务器。你可以批量使用alice@test.com,bob@test.com或者任意此域名结尾的邮箱作为你的注册邮箱。

防止失联,关注微信公众号:码道工程。

本文作者:小码哥

本文链接:http://www.tnt0.com/archives/1

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!

0 条评论

请先登陆注册

已登录,注销 取消