本文改自
[网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱

之前写的爬虫单子,代码已经跑了快3个月了,后续又增加了一些需求,修改了一些小bug

如果需要学习的话,上面的链接文章有分析过程,涉及的一些参数,上面博文也有说明

改动:

  1. 修复了爬虫过程中,qq邮箱发送邮件频率过快,帐号暂时封禁导致的程序异常退出
  2. 修复了程序定时显示时间错误问题
  3. 增加了股票涨幅限制参数
  4. 取消爬取重复数据发送
  5. 限制主力资金范围
  6. 剔除股票代码开头号(如,不需要300,688开头的)
  7. 剔除股票名称包含关键词(如,不需要包含’ST’的股票)
  8. 修复了已知问题

所有的参数修改,均 main 函数下面修改
问题解释:

  1. 发送qq邮箱可添加多个邮箱,在 senders中的列表里添加,第一个参数是授权码,2为邮箱。关于获取授权码及其它一系列问题,均在上述博文中说明过,本文不再重复
  2. 股票涨幅限制为范围限制。如果不需要,可设置参数范围较大,或自行修改程序代码。注释掉参数,就会报错
  3. 获取的每个股票数据,只发送一次
  4. 主力资金范围同3
  5. 剔除股票开头,可设置多个。如果不需要,可以删除列表里面的股票代码开头。当输入多个开头时,请保证所有开头的长度一致。如[300, 688]正确,[300, 68]错误。股票代码开头以第一个参数长度为准。长度不同会造成股票无法限制,但不会报错
  6. 股票名称关键词,如果不需要,可删除内容,但不要注释掉
  7. 修复已知问题,代码能持续运行,捕获异常。如果您发现程序未知错误导致异常退出,请在评论区指出。
# -*- coding: UTF-8 -*-
import random
import sys
import pyperclip
import requests
import re
import json
import time
import pandas as pd
import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart'''
需求:http://data.eastmoney.com/zjlx/detail.html前50,主力占比16.4以上,涨幅4.4以上,超大单占比9.4以上,成交量占前五日平均值的的0.6-1.1,换手率不超8参数我可以自行修改,出现过的就不用再出现了,邮件或其他方式提醒,实时的。
''''''
参数说明:f2: 最新价     f3: 今日涨跌幅    f12: 股票代码   f14: 股票名称今日主力净流入:f62: 净额     f184今日超大单净流入:f66: 净额     f69: 净占比今日大单净流入:f72: 净额     f75: 净占比今日中单净流入:f78: 净额     f81: 净占比今日小单净流入:f84: 净额     f87: 净占比f168: 换手率f47: 成交量f124
''''''f47数据不对 113行
'''# requests-exceptions-sslerror  : dh key too small
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
try:requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += 'HIGH:!DH:!aNULL'
except AttributeError:# no pyopenssl support used / needed / availablepass# disable warnings
requests.packages.urllib3.disable_warnings()class Variable:def __init__(self, zhuli, zhangfu, chaodadan, chengjiaoliang:list, huanshoulv, num, codehead, zhuliarea, namehead):self.zhuli = zhuliself.zhangfu = zhangfuself.chaodadan = chaodadanself.chengjiaoliang = chengjiaoliangself.huanshoulv = huanshoulvself.num = numself.all = []self.head = codeheadself.namehead = nameheadself.zhuliarea = zhuliarea# self.now = time.localtime().tm_mon*30 + time.localtime().tm_mday      # 取近五日的,不用判断时间self.ua = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36",# "Host":"push2.eastmoney.com","Connection":"keep-aliv","Cache-Control":"max-age=0"}class Spider:def __init__(self, Vb:Variable):self.url = "http://data.eastmoney.com/zjlx/detail.html"self.HomePageUrl = "http://push2.eastmoney.com/api/qt/clist/get?cb=jQuery112304456859063185632_1636024376116&fid=f62&po=1&pz={pz}&pn=1&np=1&fltt=2&invt=2&ut=b2884a393a59ad64002292a3e90d46a5&fs=m%3A0%2Bt%3A6%2Bf%3A!2,m%3A0%2Bt%3A13%2Bf%3A!2,m%3A0%2Bt%3A80%2Bf%3A!2,m%3A1%2Bt%3A2%2Bf%3A!2,m%3A1%2Bt%3A23%2Bf%3A!2,m%3A0%2Bt%3A7%2Bf%3A!2,m%3A1%2Bt%3A3%2Bf%3A!2&fields=f12,f14,f2,f3,f62,f184,f66,f69,f72,f75,f78,f81,f84,f87,f204,f205,f124,f1,f13"self.klineApi = "http://push2his.eastmoney.com/api/qt/stock/kline/get?fields1=f1,f2,f3,f4,f5&fields2=f56&fqt=0&end=29991010&ut=fa5fd1943c7b386f172d6893dbfba10b&cb=jQuery1123038436182619159487_1636971507184&klt=101&secid={f13}.{f12}&fqt=1&lmt=6"self.f47Api = "http://push2.eastmoney.com/api/qt/stock/get?fltt=2&invt=2&secid={f13}.{f12}&fields=f47,f168,f43,f46&ut=b2884a393a59ad64002292a3e90d46a5&cb=jQuery11230690409531564167_1636970393200"self.vb = Vbself.namelist = []self.retry = 0self.copy = Falsedef HomePageGet(self):      # 获取主页数据while True:response = self.request(self.HomePageUrl.format(pz=self.vb.num))if isinstance(response, bool):time.sleep(10)else:break# 获取 data 列表return self.dataGet(response)['diff']def request(self, url):while True:try:response = requests.get(url, headers=self.vb.ua, verify=False, timeout=2)self.vb.retry = 0return responseexcept:self.vb.retry += 1if self.vb.retry == 3:self.vb.retry = 0return False# 前50,主力占比16.4以上,涨幅4.4以上,超大单占比9.4以上,换手率不超8%,成交量占前五日平均值的0.6-1.1# 成交量不能筛选,得通过后续请求# 初次筛选def FirstClean(self, diff:list):        # 主页数据清洗nowdata = []# 空数据if diff[0]['f184'] == '-':return nowdatatry:headlength = len(str(self.vb.head[0]))except:headlength = Falsefor i in diff:if i['f184']>self.vb.zhuli:     # 主力占比if i['f3']>self.vb.zhangfu[0] and i['f3']<self.vb.zhangfu[1]:     # 涨幅if i['f69']>self.vb.chaodadan:      # 超大单# 股票开头和股票名称if headlength and self.vb.namehead!=None:if (int(i['f12'][:headlength]) not in self.vb.head) and self.vb.namehead not in i['f14']:nowdata.append(i)elif headlength:if int(i['f12'][:headlength]) not in self.vb.head:nowdata.append(i)elif self.vb.namehead!=None:if self.vb.namehead not in i['f14']:nowdata.append(i)else:nowdata.append(i)try:now = []for i in nowdata:if i['f62']>self.vb.zhuliarea[0] and i['f62']<self.vb.zhuliarea[1]:now.append(i)return nowexcept:return nowdata# 筛选成交量占前五日平均值的 0.6-1.1,需要请求前五日的'''成交量api:https://push2his.eastmoney.com/api/qt/stock/kline/get?fields1=f1&fields2=f55&fqt=0&end=29991010&klt=101&secid={f13}.{f12}&lmt=5'''# 筛选占前五日0.6-1.1# HomePageUrl 请求不到 f47 数据,需要单独请求def SecondClean(self, data:list):# 请求 k 线图数据,需要更改 secid,# secid 由两部份组成, f13.f12result = []for line in data:response = self.request(self.klineApi.format(f13=line['f13'], f12=line['f12']))if not response:continueklines = self.dataGet(response)['klines']kline = []# for k in klines:#     kline.append(float(k))try:for i in range(5):kline.append(float(klines[i]))except:continuefiveday = sum(kline)/5# f47response = self.request(self.f47Api.format(f13=line['f13'], f12=line['f12']))if not response:continued = self.dataGet(response)if d['f168']/100>=self.vb.huanshoulv:continuetoday = d['f47']if not (d['f43']>d['f46']):print("跳过")continue# 成交量占前 5 日平均值的 0.6-1.1value = today/fivedayif (value>=self.vb.chengjiaoliang[0] and value<=self.vb.chengjiaoliang[1]):# 股票代码,名称,最新价,今日涨跌幅,今日主力净流入,占比,换手率,现价,开盘价result.append([line['f12'], line['f14'], line['f2'], str(line['f3'])+"%", self.Format(line['f62']), str(line['f184'])+"%", str(line['f69'])+'%', "%.2f" % (d['f168']/100) +"%", '%.2f'%value, d['f43'], d['f46']])return result# 数据判断是否需要保存def JudgeSave(self, data:list):line1 = [['股票代码', '名称', '最新价', '今日涨跌幅', '今日主力净流入', '今日主力占比', '超大单占比', '换手率', '比值', "现价", "开盘价"]]result = []# 筛选不重复的保存for line in data:if line[1] not in self.namelist:self.namelist.append(line[1])result.append(line)# self.namelist.append(line[1])# line.insert(0, count)# result.append(line)# count += 1result.sort(key=self.s, reverse=True)if len(result)!=0:if not self.copy:pyperclip.copy(result[0][0])self.copy = Trueprint("_"*88)for i in result:print(f"\033[31m{i[0]}\033[0m", end="\t")for b in range(1, len(i)):print(i[b], end="\t")print("|")print(" ̄"*55)# 保存文件self.vb.all = self.vb.all+resultexcelData = pd.DataFrame(line1+self.vb.all)writer = pd.ExcelWriter("股票.xlsx")excelData.to_excel(excel_writer=writer, columns=None, index=None, header=False)writer.close()return Trueelse:return False# 返回 data 字典def dataGet(self, response):d = re.compile('"data":({.*)}\);')data = re.findall(d, response.text)[0]data = json.loads(data)return datadef Format(self, data):     # 换成万或者亿if len(str(data))>8:        # 换成亿return '%.2f' % (data/(10**8)) + '亿'elif len(str(data))==8:return '%.2f' % (data / (10 ** 7)) + '千万'elif len(str(data))>4:return '%.2f' % (data / (10 ** 4)) + '万'else:return str(data)def s(self, elem):return elem[-4]def run(self):self.data = self.HomePageGet()self.data = self.FirstClean(self.data)self.data = self.SecondClean(self.data)return self.JudgeSave(self.data.copy())class QQEmail:def __init__(self, senders, senderName, receiver, receiverName):self.senders = sendersself.senderName = senderNameself.receiver = receiverself.receiverName = receiverNameself.MailLogin()# 创建smtp,登录def MailLogin(self):self.accoutGet()try:self.server = smtplib.SMTP_SSL(host='smtp.qq.com', port=465)response = self.server.login(self.sender, self.qqCode)if response[0] == 235:print("邮箱登录成功!")except Exception as e:print("邮箱登录失败!", e)def accoutGet(self):try:self.qqCode, self.sender = random.choice(self.senders.copy().remove((self.qqCode, self.sender)))except:self.qqCode, self.sender = random.choice(self.senders)def MessageBuild(self):content = MIMEText(' ')  # 邮件正文内容,需要可填写message = MIMEMultipart()message.attach(content)  # 附上正文内容message['From'] = self.senderNamemessage['To'] = self.receiverNamemessage['Subject'] = Header('股票', 'utf-8')  # 标题xlsx = MIMEApplication(open('股票.xlsx', 'rb').read())xlsx['Content-Type'] = 'application/octet-stream'xlsx.add_header('Content-Disposition', 'attachment', filename='股票.xlsx')message.attach(xlsx)return messagedef SendMail(self):retry = 0while True:try:self.server.sendmail(from_addr=self.sender, to_addrs=self.receiver, msg=self.MessageBuild().as_string())print('已发送! ', end="")breakexcept smtplib.SMTPException as e:print("邮箱登录异常,正在重试!", e)self.MailLogin()retry += 1if retry == 2:print("邮箱登录异常!五分钟后重试")time.sleep(300)retry = 0class Control(Spider, QQEmail):def __init__(self, zhuli, zhangfu, chaodadan, chengjiaoliang, huanshoulv, senders, senderName, receiver, recieverName, num, codehead, zhuliarea, namehead):# 变量类self.vb = Variable(zhuli, zhangfu, chaodadan, chengjiaoliang, huanshoulv, num, codehead, namehead, zhuliarea)# 初始化邮箱类self.qqmail = QQEmail(senders, senderName, receiver, recieverName)# 爬虫类self.spider = Spider(self.vb)def main(self, stop, end):print("爬虫启动")count = 1while True:send = self.spider.run()if send:print("获取最新股票数据!", end="")self.qqmail.SendMail()print(count, "\n\n")count += 1else:passtime.sleep(stop)if time.localtime().tm_hour == end[0]:if time.localtime().tm_min == end[1]:breakdef getTime(t:str):return [int(a) for a in t.split(":")]if __name__ == '__main__':# 配置参数zhuli = 3zhangfu = [2.5, 9.88]chaodadan = 2chengjiaoliang = [0.2, 10]# chengjiaoliang = [1, 10]huanshoulv = 0.7num = 95stop = 1剔除股票开头 = [30,68]剔除名称 = 'ST'主力净流入范围 = [10000000, 300000000]# 配置邮箱senders = [("授权码", "邮箱"),("授权码2", "邮箱2")]receiver = '接收邮箱'senderName = '发送名'receiverName = '接收者'# 启动时间start = '22:06'end = '15:00'# 准时启动start = getTime(start)end = getTime(end)# 这段是启动时间,如果注释掉就不限制时间了while True:print("距离启动还差:{}分钟".format((-time.localtime().tm_hour+start[0])*60-time.localtime().tm_min+start[1]))if time.localtime().tm_hour == start[0]:if time.localtime().tm_min == start[1]:breaktime.sleep(10)# 启动control = Control(zhuli, zhangfu, chaodadan, chengjiaoliang, huanshoulv, senders, senderName, receiver, receiverName, num, 剔除股票开头, 剔除名称, 主力净流入范围)control.main(stop, end)

[网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱相关推荐

  1. Python实训day07pm【Selenium操作网页、爬取数据-下载歌曲】

    Python实训-15天-博客汇总表 lu16 - 博客园 <--- 本篇博客详细内容!

  2. 爬虫能有多简单?看我三分钟教会你爬取百万图片。

    什么是爬虫? 如果是没有接触过爬虫的人可能会有些许疑惑,爬虫是个什么东西呢?其实爬虫的概念很简单,在互联网时代,万维网已然是大量信息的载体,如何有效地利用并提取这些信息是一个巨大的挑战.当我们使用浏览 ...

  3. python爬取内容_Python爬取数据(基础,从0开始)

    1.技术概述 爬虫,就是给网站发起请求,并从响应中提取需要的数据的自动化程序,一般有三个步骤: (1)发起请求,获取响应 (2)解析内容 (3)保存数据 当初学习该技术是因为要做疫情网页,需要准确的疫 ...

  4. python 12306查询不到车次_Python3.x 抓取12306车次信息,表格详情显示,让你学会思路,分析网站特点,爬取数据。12306车票查看器!...

    我的例子都比较适合新手,那种老司机请绕道,谢谢! ps 前言 最近学习Python,所以呢?跟大家一样,都是看看官网,看看教程,然后就准备搞一个小东西来试试,那么我使用的例子是实验楼中的12306火车 ...

  5. python 爬取数据还要下载scrapy吗_python网络爬虫之Scrapy

    本文分享的大体框架包含以下三部分 (1)首先介绍html网页,用来解析html网页的工具xpath (2)介绍python中能够进行网络爬虫的库(requests,lxml,scrapy等) (3)从 ...

  6. 网络爬虫入门:网络爬虫的目的,企业获取数据的方式,可以用于做爬虫的程序语言,爬虫爬取数据的步骤

    目录 爬取数据的目的: 1.获取大量数据,用于做数据分析 2.公司项目的测试数据,公司业务所需数据 企业获取数据的方式 1.公司自有数据 2.第三方数据平台购买(数据堂,贵阳大数据交易所) 3.爬虫爬 ...

  7. python定时爬取数据_python实现scrapy爬虫每天定时抓取数据的示例代码

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  8. 教你如何使用Java代码从网页中爬取数据到数据库中——网络爬虫精华篇

    文章目录 1:网络爬虫介绍 2:HttpClients类介绍 2.1 HttpGet参数问题 2.2 HttpPost参数问题 2.3 连接池技术问题 3:Jsoup介绍 4:动手实践如何抓取网页上数 ...

  9. 「Python爬虫系列讲解」七、基于数据库存储的 BeautifulSoup 招聘爬取

    本专栏是以杨秀璋老师爬虫著作<Python网络数据爬取及分析「从入门到精通」>为主线.个人学习理解为主要内容,以学习笔记形式编写的. 本专栏不光是自己的一个学习分享,也希望能给您普及一些关 ...

最新文章

  1. 写在前面,白话 Yaf 探秘与深入
  2. 面向对象 (接口 Interface)
  3. React开发(175):注意在回调里面重新渲染列表
  4. java循环遍历类属性_java循环遍历类属性 get 和set值方法
  5. HTML常用标签、特殊字符、路径
  6. 数据科学 IPython 笔记本 8.7 密度和等高线图
  7. 位图缩放代码,如何伸拉图片,图片处理
  8. 《java学习二》jvm性能优化-----认识jvm
  9. Velocity基本常用语法
  10. 关于adb驱动的安装
  11. 对2-9取余的计算方法
  12. 一级域名和二级域名的差异
  13. 第三次作业 软件产品同质化问题
  14. 标准生物钟作息时间表
  15. 【笔记】29元microbit套装如何玩——套装硬件简介
  16. WLAN室内、室外无线信号覆盖解决方案
  17. Win10添加简体中文美式键盘的方法
  18. Java的NumberFormat介绍
  19. AI安全对抗赛:给你的人工智能装上杀毒软件
  20. 新一代企业IT架构到底是什么?云原生?低代码?

热门文章

  1. AWS攻略——Peering连接VPC
  2. 怎样在手机自带的邮件服务器,如何在手机上收发学校邮箱信件
  3. 江西 南昌 富士康 java,好消息!富士康智能科技小镇落户小蓝经开区!总投资达110亿元...
  4. Freeswitch集成AMR编码
  5. 无法解析的外部符号__imp__fprintf和 __imp____iob_func,SDL2
  6. execve系统调用_execve系统调用分析
  7. 探索java的 protect/private变量
  8. CSS 笔记(十二):预处理器 —— Less
  9. docker 安装mysql、canal、redis实现redis和mysql缓存一致性
  10. 十五年例后的深思--极度尴尬懊悔自卑倔强