可以说这是一个需求吧, 因为只接触过一点Python, 所以大部分代码基于python-爬虫:获取163邮箱的收件箱信息列表, 其中的代码根据我的需求进行了部分更改, 核心部分并没有做更改. 整体代码不做解释, 因为目前还不会. 具体可以查看之前提到的文章.
需求是需要登录好几个账号进行查看, 看一下有没有收到指定查找
的邮件, 所以想着通过python直接拉取看结果会快一点, 于是有了下文.
此文仅做自我记录.
另外有几个问题想请教一下, 路过的围观一下:
- 这段代码在win平台中运行不会报错, 但是切换到mac上之后会报错, 具体错误看不懂, 好像是request模块的问题. 因为最终使用实在mac平台上的, 刚开始以为通用, win平台码代码, 测试方便, 所以直接就开改了.
- 通过
py2app
和pyinstaller
进行程序的打包, 打包过程中没有任何报错, 最后执行文件都生产了, 但是无法运行, 打开失败.
这两个问题在网上找了好一会儿, 也没有找到解决方案. 先记录着, 后面再回过头来看.
代码中比较关键的部分应该是sid
的动态提取, 因为163邮箱在登陆时做了一些动态验证, 如果做不到sid
的获取, 邮箱的登录会无法进行.
在下面贴出的源代码中, 存在几个问题, 在此处进行说明:
1. 在时间的解析上存在问题
在获取邮件信息
部分,message
作为承载信息的列表, 在核心代码中获取到的时间信息有误, 邮件本身时间为2018-02-28
, 但是在获取到的时候月份上晚了一个月(2018-01-28)
的时间, 暂时未找到原因.
由于没办法理解核心代码, 就目前情况而言, 总体不影响代码的使用, 所以在后面使用了一些数据的重组来解决这个问题.
思路是: 列表里面存了n封邮件(即n个元组), 将元组进行打撒, 然后截取有用的时间信息进行重新整合, 并在月份上进行加一处理, 而手动的月份加一就会导致碰到2019年12月份
的时候就会变成2019年13月
, 虽然可以通过月份的条件判断来解决这个问题, 但是由于邮箱里没有十月份之后的邮件进行检测, 暂时先这样.
# 解析日期有问题,手动加1;
list_final_end = []
for i in range(0, len(mails)):
list_new = mails[i]
list_temp = list_new[0:3]
list_temp_add = list_new[i][3][9:18]
if list_temp_add[-1:] in range(0, 9):
months = int(list_new[3][14:16])+1
months = str(months)
list_temp_add = [list_new[3][9:13]+months+list_new[3][17:19]]
else:
months = int(list_new[3][14:15])+1
months = str(months)
list_temp_add = [list_new[3][9:13]+'0'+months+list_new[3][16:18]]
list_final = [list_temp + tuple(list_temp_add)]
list_final_end += list_final
# 打印邮件
2. 指定月份邮件的提取
原本的需求是只要查看最近的邮件就可以了, 因为经常会查看, 所以并不需要很久的邮件, 如果邮箱里有很多的邮件话会拉出来很多信息, 所以对代码上加了一段年月份判断进行筛选当月的邮件.
思路是: 通过导入time
模块来获取当前的年份和月份, 再从拉取并重组后的邮件数据中提取年月, 按照年->月
的先后顺序进行筛选, 只提取当月的邮件. 但因为是提取的当月的邮件, 所以月底最后一天不允许的话就会漏掉这些邮件, 比较尴尬. 当然, 其实简单点的话可以在获取到需要的信息之后, 再做单独的判断来进行对应的筛选.
# 打印邮件
print('*' * 50)
print('*' * 50)
print('开始打印收件箱列表.')
print('登录邮箱:', self.username)
print('收件列表如下:')
print('*' * 50)
print('*' * 50)
for mail in list_final_end:
today_year = time.strftime("%Y", time.localtime()) #获取当前年份
today_month = time.strftime("%m", time.localtime()) #获取当前月份
mail_year = mail[3][0:4] #从数据中提取邮件的年份
mail_month = mail[3][4:6] #从数据中提取邮件的月份
if mail_year == today_year: # 年份对比
if mail_month == today_month: #月份对比
print('发送时间:', mail[3], '-', '主题:', mail[2], '-', '发件人:', mail[0])
print('-' * 50)
else:
pass
else:
pass
3. 未知问题
还有部分问题未进行验证, 但目前不影响代码的运行, 因为测试的邮件只有个位数, 所以没办法做到测出其他的问题.
例如list_temp_add = list_new[i][3][9:18]
这句代码, 输出的话是一个空值, 前期测试是有的, 但是改着改着就没了, 暂时没有进行其他的测试.
代码运行结果的话可以参考下图:
源代码如下:
# -*- coding:utf-8 -*-
import urllib.request
import re
import http.cookiejar
import urllib.parse
import time
import os
class MAIL:
#初始化
def __init__(self):
#获取登录请求的网址,这个是通用的,只是一个请求登陆的URL
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"
#设置代理,以防止本地IP被封
self.proxyUrl = "http://202.106.16.36:3128"
#初始化sid码
self.sid = ""
#第一次登陆所需要的请求头request headers,这些信息可以在ntesdoor日志request header中找到,copy过来就行
self.loginHeaders = {
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,,image/webp,image/apng,*/*;q=0.8",
'Accept-Language': "zh-CN,zh;q=0.9",
'Connection': "keep-alive",
'Host': "mail.163.com",
'Referer': "http://mail.163.com/",
'User-Agent':"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36"
}
#设置用户名和密码,填上自己的即可
self.username = input('请输入邮箱地址:')
self.pwd = input('请输入密码:')
# self.username = input("邮箱地址:")
# self.pwd = input("密码:")
#post所包含的参数
self.post = {
'savelogin':"0",
'url2':"http://mail.163.com/errorpage/error163.htm",
'username':self.username,
'password':self.pwd
}
# 对post编码转换
self.postData = urllib.parse.urlencode(self.post).encode('utf8')
# 使用http.cookiejar.CookieJar()创建CookieJar对象
self.cjar = http.cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
self.cookie = urllib.request.HTTPCookieProcessor(self.cjar)
self.opener = urllib.request.build_opener(self.cookie)
# 将opener安装为全局
urllib.request.install_opener(self.opener)
#模拟登陆并获取sid码
def loginPage(self):
try:
#发出一个请求
self.request = urllib.request.Request(self.loginUrl,self.postData,self.loginHeaders)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read().decode("utf8"))
#得到响应
self.response = urllib.request.urlopen(self.request)
#需要将响应中的内容用read读取出来获得网页代码,网页编码为utf-8
self.content = self.response.read().decode("utf8")
#打印获得的网页代码
# print(self.content)
# 设定提取sid码的正则表达式
self.sidpattern = re.compile('sid=(.*?)&', re.S)
self.result = re.search(self.sidpattern, self.content)
self.sid = self.result.group(1)
# print('+'*50)
# print("sid=", self.sid)
#通过sid码获得邮箱收件箱信息
def messageList(self):
#重定向至收件箱的网址
listUrl = 'http://mail.163.com/js6/s?sid=%s&func=mbox:listMessages&TopTabReaderShow=1&TopTabLofterShow=1&welcome_welcomemodule_mailrecom_click=1&LeftNavfolder1Click=1&mbox_folder_enter=1'%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=%suCFJZNnnRnInrsigqunnSrQXsvMMqctH&df=mail163_letter"%self.sid,
'User-Agent':"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36"
}
#发出请求并获得响应
request = urllib.request.Request(listUrl, headers=Headers)
response = self.opener.open(request)
#提取响应的页面内容,里面是收件箱的信息
content = response.read().decode('utf-8')
return content
#获取邮件信息
def getmail(self):
messages = self.messageList()
# print(messages)
pattern = re.compile('from..(.*?),.*?to..(.*?),.*?subject..(.*?),.*?sentDate..(.*?),\n.*?receivedDate..(.*?),\n', re.S)
mails = re.findall(pattern, messages)
# print("+"*50)
# 解析日期有问题, 月份需要手动加1, 遇12则变为13;
list_final_end = []
for i in range(0, len(mails)):
list_new = mails[i]
list_temp = list_new[0:3]
list_temp_add = list_new[i][3][9:18]
if list_temp_add[-1:] in range(0, 9):
months = int(list_new[3][14:16])+1
months = str(months)
list_temp_add = [list_new[3][9:13]+months+list_new[3][17:19]]
else:
months = int(list_new[3][14:15])+1
months = str(months)
list_temp_add = [list_new[3][9:13]+'0'+months+list_new[3][16:18]]
list_final = [list_temp + tuple(list_temp_add)]
list_final_end += list_final
# 打印邮件
print('*' * 50)
print('*' * 50)
print('开始打印收件箱列表.')
print('登录邮箱:', self.username)
print('收件列表如下:')
print('*' * 50)
print('*' * 50)
#对当前年份和月份的邮件进行筛选
for mail in list_final_end:
today_year = time.strftime("%Y", time.localtime())
today_month = time.strftime("%m", time.localtime())
mail_year = mail[3][0:4]
mail_month = mail[3][4:6]
if mail_year == today_year:
if mail_month == today_month:
print('发送时间:', mail[3], '-', '主题:', mail[2], '-', '发件人:', mail[0])
print('-' * 50)
else:
pass
else:
pass
mail=MAIL()
mail.loginPage()
mail.getmail()
os.system('pause')
网友评论