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或者任意此域名结尾的邮箱作为你的注册邮箱。
防止失联,关注微信公众号:码道工程。
请先登陆 或 注册