美文网首页Python
python 3.7 使用requests 爬取 163邮件列表

python 3.7 使用requests 爬取 163邮件列表

作者: ocarol | 来源:发表于2019-09-25 19:23 被阅读0次

    最近想使用网易邮箱批量注册几个网站小号,注册时需要获取邮箱收到的注册码,一个一个的点开邮件太麻烦,于是就产生了写这个脚本的想法,中间也遇到一些问题,会在文章中详细的解说。

    本文将使用 requests 库来实现需求,当然也可以使用 urllibimaplibselenium

    • urllib 实现过程跟requests相近;
    • imaplib 应用于开启了 IMAP/SMTP服务 的场景;
    • selenium多应用于自动化测试中,结合浏览器使用的;

    接下来要实现我的小目标,首先先分解下功能:

    • 1.实现163邮箱自动登录
    • 2.获取邮件列表
    • 3.找到收到验证码的邮件(由于某些原因,本文忽略此步)
    • 4.抓取邮件详细内容

    先提前说一下,实现的过程遇到的一些问题:

    • SSL校验问题
    • 抓取邮件详细内容时,一直提示登录超时

    以上问题都已解决,接下来细说一下实现的过程

    一、实现163邮箱自动登录

    思路:使用账号密码,获取 sid 和 cookie

    登录部分没有什么难点,主要是url找对,就没问题了,代码如下:

    import requests
    import re
    import urllib3
    
    #忽略证书警告
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    class MAIL163:
        def __init__(self, username, password):
            self.session = requests.Session()
    
            self.username = username
            self.password = password
            self.sid = None
    
        def login(self):
            loginUrl = "https://mail.163.com/entry/cgi/ntesdoor?style=-1&df=mail163_letter&net=&language=-1&from=web&race=&iframe=1&product=mail163&funcid=loginone&passtype=1&allssl=true&url2=https://mail.163.com/errorpage/error163.htm"
            headers = {
                'Referer': "https://mail.163.com/",
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
    
            postData = {
                'savelogin': "0",
                'url2': "http://mail.163.com/errorpage/error163.htm",
                'username': self.username,
                'password': self.password
            }
    
            response = self.session.post(loginUrl, headers=headers, data=postData, verify=False)
            #提取sid,获取邮件信息需要使用它
            pattern = re.compile(r'sid=(.*?)&', re.S)
            self.sid = re.search(pattern, response.text).group(1)
    
    

    二、获取邮件列表

    思路:利用登录获取的 sid 和 cookie ,请求数据

    获取列表部分,写的时候遇到了点问题,主要是获取mail的各种信息,当时用 charles抓包时,返回的数据是json格式的,但是用requests请求,得到响应结果,进行解析json时,提示格式错误:

    Expecting property name enclosed in double quotes: line 1 column 2(char 1)
    

    后来找到了解决办法:使用demjson的包来处理,参照文章,但是最后我还是选择了使用正则匹配(没有原因),代码如下:

    
        def messageList(self):
            listUrl = 'https://mail.163.com/js6/s?sid=%s&func=mbox:listMessages' % self.sid
        
            Headers = {
                'Accept': "text/javascript",
                'Accept-Language': "zh-CN,zh;q=0.9",
                'Connection': "keep-alive",
                'Host': "mail.163.com",
                'Referer': "https://mail.163.com/js6/main.jsp?sid=%s&df=mail163_letter" % self.sid,
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
    
            response = self.session.post(listUrl, headers=Headers, verify=False)
    
            pattern = re.compile(
                "id..'(.*?)',.*?from..'(.*?)',.*?to..'(.*?)',.*?subject..'(.*?)',.*?sentDate..(.*?),\n.*?receivedDate..(.*?),.*?hmid..(.*?),\n",
                re.S)
            mails = re.findall(pattern, response.text)
            for mail in mails:
                mid = mail[0]
                print('-' * 45)
                print('mid:', mid)
                print('发件人:', mail[1], '主题:', mail[3], '发送时间:', mail[4])
                print('收件人:', mail[2], u'接收时间:', mail[5])
    
    

    三、抓取邮件详细内容

    思路:利用登录获取的 sid 和 cookie、邮件列表获取的 mid ,来请求数据

    这部分是卡住我的关键点,headers改来改去的,始终获取不到邮件内容,查阅了一些文章,说是sid失效的原因,但是我用charles抓包,sid从没有失效过,我猜想应该是哪里少了参数,于是仔细对比charles请求的headers、cookie、表单等一切信息,发现需要在原 cookie中新增sid内容,对应的字段名为‘Coremail.sid’,具体代码如下:

    
     def message(self, mid):
            Headers = {
                'Accept': "text/javascript",
                'Accept-Language': "zh-CN,zh;q=0.9",
                'Connection': "keep-alive",
                'Host': "mail.163.com",
                'Referer': "https://mail.163.com/js6/main.jsp?sid=%s&df=mail163_letter" % self.sid,
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
            
            #cookie加上这个,才能获取邮件详情
            cookie = {
                'Coremail.sid': self.sid,
            }
    
            url = 'https://mail.163.com/js6/read/readhtml.jsp?mid=%s&userType=ud&font=15&color=064977' % mid
            requests.utils.add_dict_to_cookiejar(self.session.cookies, cookie)
            response = self.session.get(url, headers=Headers, verify=False)
    
            print('邮件详情 =====>')
            print(response.text)
    
    

    四、最后一步:将所有功能串联起来

    email_163.py整体的代码如下:

    #!/usr/bin/env
    # -*- coding:utf-8 -*-
    import requests
    import re
    import json
    import urllib3
    
    # 忽略证书警告
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    class MAIL163:
        def __init__(self, username, password):
            self.session = requests.Session()
    
            self.username = username
            self.password = password
            self.sid = None
    
        def login(self):
            loginUrl = "https://mail.163.com/entry/cgi/ntesdoor?style=-1&df=mail163_letter&net=&language=-1&from=web&race=&iframe=1&product=mail163&funcid=loginone&passtype=1&allssl=true&url2=https://mail.163.com/errorpage/error163.htm"
            headers = {
                'Referer': "https://mail.163.com/",
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
    
            postData = {
                'savelogin': "0",
                'url2': "http://mail.163.com/errorpage/error163.htm",
                'username': self.username,
                'password': self.password
            }
    
            response = self.session.post(loginUrl, headers=headers, data=postData, verify=False)
            #提取sid,获取邮件信息需要使用它
            pattern = re.compile(r'sid=(.*?)&', re.S)
            self.sid = re.search(pattern, response.text).group(1)
    
        # 通过sid码获得邮箱收件箱信息
        def messageList(self):
            listUrl = 'https://mail.163.com/js6/s?sid=%s&func=mbox:listMessages' % self.sid
            # 新的请求头
            Headers = {
                'Accept': "text/javascript",
                'Accept-Language': "zh-CN,zh;q=0.9",
                'Connection': "keep-alive",
                'Host': "mail.163.com",
                'Referer': "https://mail.163.com/js6/main.jsp?sid=%s&df=mail163_letter" % self.sid,
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
    
            response = self.session.post(listUrl, headers=Headers, verify=False)
    
            pattern = re.compile(
                "id..'(.*?)',.*?from..'(.*?)',.*?to..'(.*?)',.*?subject..'(.*?)',.*?sentDate..(.*?),\n.*?receivedDate..(.*?),.*?hmid..(.*?),\n",
                re.S)
            mails = re.findall(pattern, response.text)
    
            for mail in mails:
                mid = mail[0]
                print('-' * 45)
                print('id:', mid)
                print('发件人:', mail[1], '主题:', mail[3], '发送时间:', mail[4])
                print('收件人:', mail[2], u'接收时间:', mail[5])
                self.message(mid)
    
        def message(self, mid):
            Headers = {
                'Accept': "text/javascript",
                'Accept-Language': "zh-CN,zh;q=0.9",
                'Connection': "keep-alive",
                'Host': "mail.163.com",
                'Referer': "https://mail.163.com/js6/main.jsp?sid=%s&df=mail163_letter" % self.sid,
                'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15"
            }
    
            #cookie加上这个,才能获取邮件详情
            cookie = {
                'Coremail.sid': self.sid,
            }
    
            url = 'https://mail.163.com/js6/read/readhtml.jsp?mid=%s&userType=ud&font=15&color=064977' % mid
            requests.utils.add_dict_to_cookiejar(self.session.cookies, cookie)
            response = self.session.get(url, headers=Headers, verify=False)
    
            print('邮件详情 =====>')
            print(response.text)
    
    
    if __name__ == "__main__":
        mail = MAIL163('*****@163.com', '****')
        mail.login()
        mail.messageList()
    
    

    参考文章:

    相关文章

      网友评论

        本文标题:python 3.7 使用requests 爬取 163邮件列表

        本文链接:https://www.haomeiwen.com/subject/opewuctx.html