keepython 发表于 2020-2-1 14:36

利用用python爬虫实现定时QQ邮箱推送英文文章,辅助学习英语,再也不用担心英文不...

自从在上海上了大学后愈加的感觉英文的重要性,其实自己学习英文的意愿还是有的,但是就是总因为各种琐碎的小事忘记,于是想要借用自己擅长的python帮助自己。

当然,定时推送英文文章只是一部分,接下来我准备根据[艾宾浩斯遗忘曲线](https://baike.baidu.com/item/%E9%81%97%E5%BF%98%E6%9B%B2%E7%BA%BF/7278665?fromtitle=%E8%89%BE%E5%AE%BE%E6%B5%A9%E6%96%AF%E9%81%97%E5%BF%98%E6%9B%B2%E7%BA%BF&fromid=3905802)定时的给自己推送单词,帮助自己提升英文水评。

当然,如果各位有什么好的想法与建议可以提出来,我们一起实现。
___
项目总分为两个总模块,分别是**爬虫模块**与**邮件发送模块**
___
首先,我们来看爬虫模块:
### 爬虫模块
爬虫模块分为两个部分分别是**索引爬虫**和**文章爬虫**,其功能分别是爬取文章的链接和爬取文章的内容。

分别选择[可可英语的双语新闻](http://www.kekenet.com/read/news/)与[沪江英语的双语新闻](https://www.hjenglish.com/new/fanyiyuedu/)
##### 1 索引爬虫
代码的详细解释都在对应的注释里面
index_spider.py

```
#auther : keepython
import requests
from lxml import etree
import time
import re

#http://www.kekenet.com/read/news/
#https://www.hjenglish.com/new/fanyiyuedu/
#index_spider是可可英语的索引爬虫
def index_spider():
        index_url = 'http://www.kekenet.com/read/news/'#将双语新闻的链接内置在函数里面
        page_html = requests.get(index_url)#用get的方式拿到对应页面的内容
        page_html.encoding = 'utf-8'#进行utf8编码
        selector = etree.HTML(page_html.text)#对经过编码的内容进行进一步处理方便使用xpath提取链接
        # 使用xpath语法从当前页面的源代码中提取数据由于xpath筛选后返回的是列表格式的数据,我们选择第一条也就是最新的新闻
        url = selector.xpath('//ul[@id="menu-list"]/li/h2/a/@href')
        return url #用return的方法传递我们利用index)spider抓取到的文章地址

#hujiang_xindex_spider是沪江英语的索引爬虫,两个索引爬虫的结构基本相似,但是也有一些不同
def hujiang_index_spider():
        index_url = 'https://www.hjenglish.com/new/fanyiyuedu/'#将沪江英语的链接内置在函数里面
        page_html = requests.get(index_url)
        page_html.encoding = 'utf-8'
        selector = etree.HTML(page_html.text)
        url = selector.xpath('//li[@class="article-item"]/a/@href')
        # 创建一个空列表,由于我么上面爬取到的url没有主域名所以需要倚靠字符串的拼接完成文章域名的构建同时返回对应的文章链接
        urls = []
        for i in url :
                i = 'https://www.hjenglish.com'+i
                urls.append(i)
        # print(urls)
        return urls#返回构建好的文章链接的第一条,用于后面文章内容的爬取


```
##### 2 文章爬虫
废话不多说    **show me the code**
second_spider.py
```
#auther : keepython
import requests
from lxml import etree
import time
import re
#可可英语文章爬虫
def seconde_spider(page_url):
        page_html = requests.get(page_url)#用index_spider传入的文章地址开始爬取文章内容
        page_html.encoding = 'utf-8'#使用utf8形式进行编码
        selector = etree.HTML(page_html.text) #将编码后的网页内容处理为可以进行xpath筛选的形式
        title = selector.xpath('//h1[@id="nrtitle"]/text()')#爬取文章的标题
        txt_file = title+'.txt'#使用字符串拼接的形式构建文件名称
        eng_text = selector.xpath('//div[@class="qh_en"]/p/text()')#提取英文文章内容
        ch_text = selector.xpath('//div[@class="qh_zg"]/p/text()')#提取中文文章内容
        time_stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())#使用time模块以对应的年-月日 小时 分钟 秒的形式
        file_path = '.\\data\\keke\\'+txt_file#构建文章地址,注意这里是绝对路径因为在centos中定时任务只能读取绝对路径
        with open(file_path,'a') as f: #用with open的形式创建并打开文件
                #接下来就是将爬取到的文章内容写入对应的txt文档中
                f.write(title)
                f.write('\n')
                f.write(time_stamp)
                f.write('\n')
                for i in eng_text :
                        f.write(i)
                        f.write('\n')
                f.write('\n\n')
                for j in ch_text:
                        f.write(j)
                        f.write('\n')
        return file_path#返回文档的路径
#沪江英语文章爬虫,内容基本相同
def hujiang_second_spider(page_url):
        page_html = requests.get(page_url)
        page_html.encoding = 'utf-8'
        selector = etree.HTML(page_html.text)
        title = selector.xpath('//h1[@class="title"]/text()')
        txt_file = title + '.txt'
        # eng_title = selector.xpath('//div[@class="langs_en"]/strong/text()')
        eng_text = selector.xpath('//div[@class="langs_en"]/text()|//div[@class="langs_en"]/strong/text()')
        ch_text = selector.xpath('//div[@class="langs_cn"]/text()|div[@class="langs_cn"]/strong/text()')
        time_stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

        file_path = './data/hujiang/' + txt_file
        with open(file_path,'a') as f:
                f.write(title)
                f.write('\n')
                f.write(time_stamp)
                f.write('\n')
                for i in eng_text :
                        f.write(i)
                        f.write('\n')
                f.write('\n\n')
                for j in ch_text:
                        f.write(j)
                        f.write('\n')

        return file_path
```
___
### 邮件发送模块
mail_send_code.py

```
#auther : kelang
import smtplib
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.application import MIMEApplication
from index_spider import index_spider,hujiang_index_spider
from second_spider import seconde_spider,hujiang_second_spider


message = MIMEMultipart()
msg_from = '*************'# 发送方邮箱地址。
password = '*************'# 发送方QQ邮箱授权码,不是QQ邮箱密码。
msg_to = '**************'
msg_to_1 = '**************'# 收件人邮箱地址。

#文件生成,这里分别调用上面的函数生成txt文件
page_url = index_spider()
file_path = seconde_spider(page_url=page_url)

page_url_2 = hujiang_index_spider()
file_path_2 = hujiang_second_spider(page_url=page_url_2)
#文件生成

message = MIMEMultipart()
message['From'] = msg_from# 发送者
message['To'] = msg_to# 接收者
# 邮件标题
subject = '每日英文新闻'.center(80,'=')
message['Subject'] = Header(subject, 'utf-8')

#添加附件模块
part = MIMEApplication(open(file_path, 'rb').read())
part.add_header('Content-Disposition', 'attachment', filename=file_path)

part_2 = MIMEApplication(open(file_path_2, 'rb').read())
part_2.add_header('Content-Disposition', 'attachment', filename=file_path_2)

#添加多个邮件
message.attach(part)
message.attach(part_2)

try:
        client = smtplib.SMTP_SSL('smtp.qq.com', smtplib.SMTP_SSL_PORT)
        print("连接到邮件服务器成功")

        client.login(msg_from, password)
        print("登录成功")
        client.sendmail(msg_from, msg_to, message.as_string())
        print("发送成功")
except smtplib.SMTPException as e:
        print("发送邮件异常")
finally:
        client.quit()


```
___
最后是设置centos7的定时任务了,我这里用的是阿里云的ECS,这一步需要着重注意绝对路径的问题。

**编辑crontab配置**这一步详细解释可以看这里:

(https://blog.csdn.net/qq874455953/article/details/81586508)

```
crontab -e
```
**编写配置文件**

当打开配置文件的时候,我们可以看到类似的配置代码。每一行都代表一个定时任务 , 我们要做的就是新添加一行配置代码。

**重启服务**

```
service crond restart
```
最终就完成啦

欢迎留言交流学习,有什么疑问也可以交流,如果聊的开心还可以多一个朋友。

TiMiii 发表于 2020-2-1 17:18

本帖最后由 TiMiii 于 2020-2-1 17:28 编辑

作者你好。怎么在crontab中保证三个py文件执行顺序呢,我知道你这个肯定是三个py文件先后顺序执行才行的。比如我设置每两个小时执行一次crontab任务,那这正常的话3个文件估计会同时执行啊。。

keepython 发表于 2020-2-1 18:49

TiMiii 发表于 2020-2-1 17:18
作者你好。怎么在crontab中保证三个py文件执行顺序呢,我知道你这个肯定是三个py文件先后顺序执行才行的。 ...
这三个文件是有调用关系的,如果仔细看看源码你就会发现只需要调用mail_send_code.py就可以了,希望能帮到你。

q510 发表于 2020-2-1 18:49

感谢分享

TiMiii 发表于 2020-2-1 19:10

keepython 发表于 2020-2-1 18:49
这三个文件是有调用关系的,如果仔细看看源码你就会发现只需要调用mail_send_code.py就可以了,希望能帮 ...

谢谢作者指点,试了下直接运行邮件模块就可以了。

BlovedCQ 发表于 2020-2-1 23:51

支持原创,和有想法的你。

keepython 发表于 2020-2-3 20:45

已经完成了艾宾浩斯单词学习提醒,已经正在服务器上测试啦,估计很快就能写完教程,同时也准备在github上上线项目,欢迎大家支持:lol

yimn 发表于 2020-7-24 19:03

顶一个,谢谢卤煮的分享
页: [1]
查看完整版本: 利用用python爬虫实现定时QQ邮箱推送英文文章,辅助学习英语,再也不用担心英文不...