146-在不断地报错和试错过程中提升自己-R发邮件
刘小泽写于19.11.9 记得之前Jimmy说过,他给别人发邮件经常使用R包,这一点就很新鲜,并且大大方便了批量发送。我感觉很好奇,就想尝试一下,看看能不能成功
首先搜索使用了什么R包
只需要把自己的需求简单描述,浏览器都能给我们答案,例如:
发现搜到的大多指向了mailR
这个包
明确了方向,开始前进
以下操作基于Mac Mojave的Rstudio,R版本3.6.1
如果想操作,一定要先看完,中间有些坑就可以帮你避免
貌似这个包运行很简单,安装包完事一句send.mail(...)
函数就搞定啦!
其实不然,首先会遇到的坑就是解决它的依赖
这个包依赖于java
其实碰到java就有点头疼了,我对java的初始看法是:它的版本复杂,而且用不对就运行不成功,报错也稀奇古怪。这一切的认知都”归功“于IGV,它也是个难缠的家伙,记得当时安装软件还花费了一些功夫: 必备可视化Integrative Genomic Viewer(IGV)
不过没关系,先探索一下。直接install.packages('mailR',dependencies = T)
安装肯定不行,因为它事先需要安装一个rJava
的依赖包。
rJava的安装踩坑
运行这句命令install.packages('rJava',dependencies = T)
如果不出现报错,那么恭喜你,说明你的电脑中java版本是正确的。
不过大多数情况没有这么巧,很有可能出现以下报错:
报错信息很长,但不要害怕!我们要相信写R包的作者都有一颗善心,它们一定会把解决方案或者线索写在报错信息中。能不能成功和作者”呼应“上,就看自己了
# 出现报错(我们只看有用的信息)
# Unable to find any JVMs matching version "(null)".
# No Java runtime present, try --request to install.
# Library not loaded: /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/lib/server/libjvm.dylib
可见它在说,我的电脑目前mac上只有JDK 13,估计是版本太高。看一眼报错,这不是让我们去用jdk-11.0.1.jdk这个版本吗?
tip:JDK的版本命名是这样的:jdk-interim.update.patch.jdk
那么就要去找对应的历史版本:https://jdk.java.net/archive/,找到11.0.1版本后下载,结果会是一个tar.gz文件,将其解压后放在/Library/Java/JavaVirtualMachines
目录
最后使用java --version
查看版本
喜旧厌新
有了旧版本,就要删掉新版本,在terminal或者iterms中输入:
cd /Library/Java/JavaVirtualMachines
sudo rm -rf jdk-13.0.1.jdk
然后再进行旧版本的配置
sudo R CMD javareconf
结果就能看到版本变化了:Java version: 11.0.1
以上内容参考了:https://blog.csdn.net/weixin_38986122/article/details/80931223 中的”在R中安装rJava及建立连接“部分
版本正确了,再次迈出一小步
install.packages('rJava',dependencies = T)
library(rJava)
install.packages('mailR',dependencies = T)
library(mailR)
没有出现报错,可见只要按照报错的要求操作,缺啥补啥,就没问题
走到这里,其实只成功了三分之一
配置邮箱
发邮件不是这么随便的,毕竟我们登陆邮箱还要密码呢,程序不会这么智能地跳过输入密码这一步。但又为了方便快捷,省事省力地去批量发送,而且要强调保密性(总不能把自己的真实邮箱密码在代码中展示吧)。于是代码中添加了一个参数passwd
不过不要误解,这个参数不是要让你输入邮箱的密码,而是一个授权码
那么怎么获取这个授权码呢?
以163旗下的yeah.cn
邮箱为例,我们登录上以后,会在设置中找到POP3/SMTP/IMAP
选项,相信很多人都没有用过这个功能,我也是第一次,这个没关系,以后你就能教别人使用了:
这两项都需要用手机发一个短信,这个设置一步步操作就好,该打开的服务打开就行。授权码设置一个不同于密码的熟记的就好
有了这个授权码,可以看看代码怎么写了
代码很简单,一共就需要提供自己的邮箱、授权码、别人的邮箱
如果只是针对一个收件人的话:
sender <- "自己的邮箱~我的是bioinfoplanet520@yeah.net"
recipients <- c("你的收件人")
send.mail(from = sender,
to = recipients,
subject = "Program Done.",
body = "My program is finished.",
smtp = list(host.name = "smtp.yeah.net", port = 465,
user.name = "自己的邮箱~我的是bioinfoplanet520@yeah.net",
passwd = "刚才设置的授权码", ssl = TRUE),
authenticate = TRUE,
send = TRUE)
下一个坑来啦
如果这时直接运行代码,很有可能会报错,而且看上去报错信息很难懂(这也正是讨厌java报错的原因):
但没关系,我们有搜索引擎,把报错搜一下:
第一次搜索得到:https://github.com/rpremraj/mailR/issues/77
其中
wush978
这个用户说让把两个.jar文件放到下面👇的m目录# 在R中输入这个命令,就会出来这个包所在的位置 system.file("java", package = "mailR")
但根据他提供的信息,下载两个文件,还是报错。
于是先检查下载的文件,结果发现下载的两个命名有问题,都是1.2.0这样的名称,而不是.jar后缀
搜索第二次:这次搜索这两个文件
在https://stackoverflow.com/questions/20020270/java-lang-noclassdeffounderror-javax-activation-datahandler中Bill Shannon
用户提供了信息:
这两个文件的另外的下载地址是:
https://code.google.com/archive/p/javamail-android/downloads
下载发现,这次的下载命名是对的,下载的路径也是对的
记得重启Rstudio
解决了之前的加载包和运行代码的两个错误以后,进行重启。重启之后,再次尝试运行代码
这一次,惊喜出现了,等待几秒后,返回了正常的结果
然后我就在我的收件箱找到了:
总结
好,既然发一封没有问题,那么用R语言,处理批量发送邮件,也不是一件难事了
发现自己越来越不害怕、不反感报错了。而是能冷静下来,仔细思考为什么会有这种报错。相信问题是一定能够解决的,报错只会更加方便地去寻找解决方案而已