懒应该是人类第一生产力,因为太懒了,再加上很容易忘记时间,所以经常错过打新债的时间,这可都是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程序,期间遇到错误和不懂得地方也查找翻阅了很多牛人的博客,因为太多了,我能记起来的都放到博客里了并在相关位置放上了连接,大部分是找不到了。如果有借鉴您的却没有标注的,还请联系我。
最后,再次真诚的感谢各位大佬写的博客才能让我的想法得以实现!



