使用 Python 定时爬取菜谱并发送邮件:完整指南
在当今信息爆炸的时代,定期获取最新信息已成为许多人的需求。对于美食爱好者来说,定期获取最新的菜谱信息可以极大地提升烹饪体验。本文将介绍如何使用 Python 编写一个自动化脚本,定时爬取菜谱网站的数据,并通过邮件发送给您。
1. 项目概述
我们将编写一个 Python 脚本,该脚本每周五早上 7 点执行以下任务:
- 爬取菜谱数据:从指定的菜谱网站(如下厨房)爬取最新的菜谱信息,包括菜名、链接和原料。
- 发送邮件:将爬取到的菜谱信息通过邮件发送给指定的收件人。
2. 环境准备
2.1. 安装必要的 Python 库
请确保您的系统已安装 Python 3.x。然后,使用 pip
安装以下库:
pip install requests beautifulsoup4 schedule
- requests:用于发送 HTTP 请求。
- beautifulsoup4:用于解析 HTML 内容。
- schedule:用于定时执行任务。
2.2. 开启邮箱的 SMTP 服务
为了使用 Python 脚本发送电子邮件,您需要确保您的邮箱已开启 SMTP 服务。以下以 QQ 邮箱为例:
- 登录您的 QQ 邮箱。
- 进入“设置” -> “账户”。
- 在“POP3/IMAP/SMTP 服务”中,启用 IMAP/SMTP 服务。
- 生成并记录授权码(不要使用邮箱密码,使用授权码作为登录密码)。
3. 优化后的 Python 脚本
以下是优化后的 Python 脚本,包含详细注释和错误处理:
import requests
from bs4 import BeautifulSoup
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import schedule
import time
import sys
def get_user_credentials():
account = input('请输入你的邮箱:')
password = input('请输入你的邮箱密码(授权码):')
receiver = input('请输入收件人的邮箱:')
return account, password, receiver
def fetch_recipes():
url = 'http://www.xiachufang.com/explore/' # 菜谱网站URL
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
response.encoding = response.apparent_encoding
soup = BeautifulSoup(response.text, 'html.parser')
recipes = soup.find_all('div', class_='info pure-u')
list_all = ''
num = 0
for item in recipes:
num += 1
name_tag = item.find('a')
name = name_tag.text.strip()
url = 'http://www.xiachufang.com' + name_tag['href']
ingredients = item.find('p', class_='ing ellipsis').text.strip()
food_info = f'''序号:{num}
菜名:{name}
链接:{url}
原料:{ingredients}
-----------------------------
'''
list_all += food_info
return list_all
except requests.RequestException as e:
print(f"请求错误:{e}")
sys.exit(1)
def send_email(recipes_info, account, password, receiver):
mailhost = 'smtp.qq.com'
try:
qqmail = smtplib.SMTP(mailhost, 587) # 使用587端口,支持TLS
qqmail.ehlo()
qqmail.starttls()
qqmail.ehlo()
qqmail.login(account, password)
message = MIMEText(recipes_info, 'plain', 'utf-8')
subject = '每周菜谱推荐'
message['Subject'] = Header(subject, 'utf-8')
message['From'] = Header("Python 菜谱邮件", 'utf-8')
message['To'] = Header("收件人", 'utf-8')
qqmail.sendmail(account, receiver, message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print(f"邮件发送失败,错误信息:{e}")
finally:
qqmail.quit()
def job():
print("开始爬取菜谱数据")
recipes_info = fetch_recipes()
print("开始发送邮件")
account, password, receiver = get_user_credentials()
send_email(recipes_info, account, password, receiver)
print("任务完成")
if __name__ == "__main__":
print("程序已启动,每周五7点执行任务")
schedule.every().friday.at("07:00").do(job)
while True:
schedule.run_pending()
time.sleep(1)
3.1. 代码说明
-
用户凭证获取:
get_user_credentials
函数通过命令行获取用户的邮箱、密码(授权码)和收件人邮箱。
-
爬取菜谱数据:
fetch_recipes
函数发送 HTTP GET 请求到指定的菜谱网站。- 使用 BeautifulSoup 解析 HTML 内容,提取菜名、链接和原料信息。
- 返回格式化后的菜谱信息字符串。
-
发送邮件:
send_email
函数使用smtplib
连接到 SMTP 服务器,登录邮箱,并发送邮件。- 使用
MIMEText
构建邮件内容,设置主题、发件人和收件人。 - 错误处理确保在发送失败时给出提示。
-
定时任务:
- 使用
schedule
库设置每周五7点执行job
函数。 job
函数调用爬取和发送邮件的功能。
- 使用
-
主程序:
- 启动程序后,脚本会持续运行,等待每周五7点的定时任务。
3.2. 安全性考虑
- 不要在代码中硬编码敏感信息:为了安全起见,建议使用环境变量或配置文件来存储邮箱密码(授权码)。
- 使用授权码代替密码:建议使用授权码进行登录,以提高安全性。
4. 示例运行
假设您使用的是 QQ 邮箱,以下是一个示例运行过程:
请输入你的邮箱:your_email@qq.com
请输入你的邮箱密码(授权码):your_authorization_code
请输入收件人的邮箱:recipient_email@example.com
开始爬取菜谱数据
开始发送邮件
邮件发送成功
任务完成
5. 扩展功能
5.1. 使用配置文件管理敏感信息
为了提高安全性,建议使用配置文件(如 config.json
)来管理敏感信息。以下是一个示例:
{
"account": "your_email@qq.com",
"password": "your_authorization_code",
"receiver": "recipient_email@example.com"
}
修改脚本以读取配置文件:
import json
def get_user_credentials():
with open('config.json', 'r') as f:
config = json.load(f)
return config['account'], config['password'], config['receiver']
5.2. 发送 HTML 格式的邮件
如果需要发送 HTML 格式的邮件,可以修改 MIMEText
的参数:
message = MIMEText(recipes_info, 'html', 'utf-8')
5.3. 爬取更多菜谱网站
您可以扩展 fetch_recipes
函数,爬取更多菜谱网站的数据,并整合到邮件中。
6. 总结
通过本文的介绍,您已经掌握了如何使用 Python 定时爬取菜谱并发送邮件的基本方法和优化技巧。无论是为了获取最新的美食信息。
希望本文对您有所帮助,祝您编程愉快!