栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

基于Python每天爬取可转债信息并发送Email提醒【存档】

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于Python每天爬取可转债信息并发送Email提醒【存档】

前言

懒应该是人类第一生产力,因为太懒了,再加上很容易忘记时间,所以经常错过打新债的时间,这可都是money啊!所以心血来潮花了两天的时间从网上找各种资料【感谢强大的互联网和各位牛人的博客】,从0基础开始写完了这样的一个简单的程序,即使简单,但依然有点成就感的,这就来记录一下

python代码部分 爬取集思录的数据并处理

之前我就经常在集思录上看有关转债的信息,数据非常详细,网页也很简单,爬取起来也不费劲,所以就它了!

和预想的一样,网页是post请求,json格式输出,那还愣着干啥?直接写吧!

import requests
import json

# 请求网址
url = 'https://www.jisilu.cn/data/cbnew/pre_list/?___jsl=LST___t=1633347537744'
# 进行UA伪装:让爬虫对应的请求载体身份标识伪装成某一浏览器
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'
}
# 表单数据
data = {
    'progress': '',
    'rp': '22',
    'page': '1'
}
# 请求发送,并获取响应数据
dic_bond = requests.post(url, data, headers).json()
# 持久化存储
fp = open('./zhuanzhai.json', 'w', encoding='utf-8')
json.dump(dic_bond, fp=fp, ensure_ascii=False)
print('over!')

把爬取到的内容输出到zhuanzhai.json这个文件里,然后来端详一下,找到想要的数据,把它提取出来

以第一个为例,我只想知道转债代码,转债名称,转债进展信息就OK了,所以把这些数据给提出来就可以了。

需要注意的是,有些转债只是“证监会核准/同意注册”,还没有正式地申购日期,所以就没有转债代码,因为集思录本身就已经排序过了,所以用简单的if语句判断一下bond_id的值,如果是为空直接break不用看下面的数据了,有了想法操作就很简单,继续!

# 根据rows的长度来进行循环
for i in range(len(dic_bond['rows'])):
	# 判断bond_id的值是否为空
    if '' == dic_bond['rows'][i]['cell']['bond_id']:
        break
    # 获取相应数据
    bond_id = dic_bond['rows'][i]['cell']['bond_id']
    bond_nm = dic_bond['rows'][i]['cell']['bond_nm']
    progress_nm = dic_bond['rows'][i]['cell']['progress_nm']

可以观察到,方案进展这里有灰色的,那是因为这里的时间已经过期了,过期的数据要他做什么呢?当然是把他给忽略掉,想到之前提取的progress_nm的值了吗?里面就是存放着进展的信息,将它的时间提取出来与现在的时间做个对比,如果过期了同样的忽略它,没过期就把想要的数据整理一下并添加到一个数组里,方便之后发邮件

	# 今天的时间
    d1 = datetime.strptime(time.strftime("%Y-%m-%d", time.localtime()), '%Y-%m-%d')
    # 转债进展的时间
    d2 = datetime.strptime(progress_nm[:10], '%Y-%m-%d')
    # 两个时间进行比较,如果过期就直接break
    if d1 > d2:
        break
    else:
    	# 时间没过期就把想要的数据整合起来,加上
是因为发邮件我是用HTML发送的 content = '代码:' + bond_id + '
名称:' + bond_nm + '
时间:' + progress_nm[:12] + '

' # 将数据存放到一个集合里 data_list.append(content)

到这里,爬取和整理可转债的就差不多了,把上面的整合一下,就是这样了!

def web():
    url = 'https://www.jisilu.cn/data/cbnew/pre_list/?___jsl=LST___t=1633347537744'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'
    }
    data = {
        'progress': '',
        'rp': '22',
        'page': '1'
    }

    try:
        dic_bond = requests.post(url, data, headers).json()
        data_list = []
        for i in range(len(dic_bond['rows'])):
            if '' == dic_bond['rows'][i]['cell']['bond_id']:
                break
            bond_id = dic_bond['rows'][i]['cell']['bond_id']
            bond_nm = dic_bond['rows'][i]['cell']['bond_nm']
            progress_nm = dic_bond['rows'][i]['cell']['progress_nm']
            d1 = datetime.strptime(time.strftime("%Y-%m-%d", time.localtime()), '%Y-%m-%d')
            d2 = datetime.strptime(progress_nm[:10], '%Y-%m-%d')
            if d1 > d2:
                break
            else:
                content = '代码:' + bond_id + '
名称:' + bond_nm + '
时间:' + progress_nm[:12] + '

' data_list.append(content) print(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) str_data = ''.join(data_list) email(str_data) except IOError: print('异常!')
发送邮件

这里的代码是参考这位博主的:[转]简单三步,用 Python 发邮件,对发件内容修改了一下,下面就是我的代码了

def email(str_data):
	# 设置服务器所需信息
	# 邮箱服务器地址
    mail_host = 'smtp.****.cn'
	# 用户名
    mail_user = '1*****1@qq.com'
    # 密码(部分邮箱为授权码) ,比如163,QQ邮箱
    mail_pass = '******'
    # 邮件发送方邮箱地址
    sender = '1*****1@qq.com'
    # 邮件接受方邮箱地址,注意需要[]包裹,这意味着你可以写多个邮件地址群发
    receivers = ['1*****1@qq.com']
    
    # 设置email信息
    # 这里我用html的形式来发邮件
    mail_msg = """
        
          
          

集思录转债

$(data_list) """ mail_msg = mail_msg.replace("$(data_list)", str_data) # 邮件设置 message = MIMEText(mail_msg, 'html', 'utf-8') # 邮件主题 message['Subject'] = '转债申购/上市消息' # 发送方信息 message['From'] = sender # 接受方信息 message['To'] = receivers[0] # 登录并发送邮件 try: smtpObj = smtplib.SMTP() # 连接到服务器 smtpObj.connect(mail_host, 25) # 登录到服务器 smtpObj.login(mail_user, mail_pass) # 发送 mtpObj.sendmail(sender, receivers, message.as_string()) # 退出 smtpObj.quit() print('Email sent successfully') except smtplib.SMTPException as e: print('error', e) # 打印错误
定时器

因为每天都要爬取数据,所以就想到了弄个定时器,参考的是这位博主的文章Python 定时任务的实现方式,这里我是使用APScheduler定时框架来定时的,添加一个job,每周一至周五的21点执行代码

    scheduler = BlockingScheduler()
    scheduler.add_job(web, 'cron', day_of_week='1-5', hour=21, minute=0)
    scheduler.start()
整理代码

将上面所有的代码整合到一起,稍微修改一下格式,就是下面这样了

# author: 沈望舒 time:2021/10/04/0004
import requests
import time
import smtplib
from datetime import datetime
from email.mime.text import MIMEText
from apscheduler.schedulers.blocking import BlockingScheduler


def web():
    url = 'https://www.jisilu.cn/data/cbnew/pre_list/?___jsl=LST___t=1633347537744'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'
    }
    data = {
        'progress': '',
        'rp': '22',
        'page': '1'
    }

    try:
        dic_bond = requests.post(url, data, headers).json()
        data_list = []
        for i in range(len(dic_bond['rows'])):
            if '' == dic_bond['rows'][i]['cell']['bond_id']:
                break
            bond_id = dic_bond['rows'][i]['cell']['bond_id']
            bond_nm = dic_bond['rows'][i]['cell']['bond_nm']
            progress_nm = dic_bond['rows'][i]['cell']['progress_nm']
            d1 = datetime.strptime(time.strftime("%Y-%m-%d", time.localtime()), '%Y-%m-%d')
            d2 = datetime.strptime(progress_nm[:10], '%Y-%m-%d')
            if d1 > d2:
                break
            else:
                content = '代码:' + bond_id + '
名称:' + bond_nm + '
时间:' + progress_nm[:12] + '

' data_list.append(content) print(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) str_data = ''.join(data_list) email(str_data) except IOError: print('异常!') def email(str_data): mail_host = 'smtp.****.cn' mail_user = '1*****1@qq.com' mail_pass = '******' sender = '1*****1@qq.com' receivers = ['1*****1@qq.com'] mail_msg = """

集思录转债

$(data_list) """ mail_msg = mail_msg.replace("$(data_list)", str_data) message = MIMEText(mail_msg, 'html', 'utf-8') message['Subject'] = '转债申购/上市消息' message['From'] = sender message['To'] = receivers[0] try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) smtpObj.quit() print('Email sent successfully') except smtplib.SMTPException as e: print('error', e) if __name__ == '__main__': # BlockingScheduler scheduler = BlockingScheduler() scheduler.add_job(web, 'cron', day_of_week='1-5', hour=21, minute=0) scheduler.start()
python部署到服务器上

之前为了写博客所以买了个服务器,这里刚好派上用场了,把python部署到服务器上,这样的话就可以一直运行python文件了

安装python

因为是第一次在Linux环境中安装python,所以也记录一下吧,详情看这里在centos里安装Anaconda3

把文件部署到python上

首先将py文件拖到/home/python3/文件夹里,进入到该目录下,就可以执行该文件了。但是,因为想要在服务器上一直运行,即使断开ssh也能运行,所以就要进行如下操作。

因为该文件使用了apscheduler定时器,这个库在anaconda中没有,所以要单独安装pip install apscheduler,否则的话没法运行py文件

[root@centos ~]# cd /home/python3/
[root@centos python3]# ll
total 8
-rw-r--r-- 1 root root 2771 Oct  5 22:02 Convertible_bond.py
[root@kylin python3]# nohup python -u Convertible_bond.py > Convertible_bond.log 2>&1 &

该命令的意思是不挂断地运行py文件,1是标准输出,2是标准错误输出,2>&1 的意思是将标准错误 2 重定向到标准输出 &1 ,标准输出 &1 再被重定向输入到 Convertible_bond.log 文件中

同理,如果发现程序不能运行就可以看看这个日志,像上面因为没有安装相关的库导致无法运行程序,就可以通过查看日志里的错误信息就知道为什么了

使用ps -aux便可以看到这个进程了,并且即使关闭shell它依然运行

[root@centos ~]# ps -aux
root     31189  0.0  1.4 151164 26548 ?        S    Oct05   0:00 python -u Convertible_bond.py

如果想要关闭该程序,则使用kill -9 进程号PID的命令来关闭程序即可

后记

至此,该想法算是真正的实施了,到真正有转债信息的时候再检测一下有没有其他问题,到时候有错误再来更正。因为之前对python没怎么学过,所以这也算我写的第一个python程序,期间遇到错误和不懂得地方也查找翻阅了很多牛人的博客,因为太多了,我能记起来的都放到博客里了并在相关位置放上了连接,大部分是找不到了。如果有借鉴您的却没有标注的,还请联系我。
最后,再次真诚的感谢各位大佬写的博客才能让我的想法得以实现!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/300633.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号