# XueQiuSuperSpider **Repository Path**: weitinting/XueQiuSuperSpider ## Basic Information - **Project Name**: XueQiuSuperSpider - **Description**: 雪球股票信息超级爬虫 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-08-04 - **Last Updated**: 2025-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #雪球超级爬虫 ##前言 雪球网或者东方财富或者同花顺目前已经提供了很多种股票筛选方式,但是筛选方式是根据个人操作 风格来定义的,三个网站有限的筛选方式显然不能满足广大股民、程序员特别是数据分析控的要求, 基于此,本人设计了一个可以任意拓展,实现任意数据搜集与分析的爬虫程序,满足股友们的需要, 只要你能想到的数据搜集与分析策略它都能实现。 ##结构 如果把程序程序比作文学体裁,我想散文最能体现雪球超级爬虫的整体结构--形散而神不散。 整个程序的所有组件互相没有任何依赖,包括参数,组件由接口定义成三大类:Collector、 Mapper以及Consumer,功能分别为数据搜集、数据相关信息(分支信息)的组装、以及最终 的数据分析。三个接口定义了整个数据抓取生命周期的三个阶段。Mapper组件可以进行多个 嵌套,就像流水线一样,经过N个Mapper,完成一个组件的N种属性组装,当然,如果你不需 要某些属性,你完全可以跳过某些mapper,这样可以节省许多抓取时间。在参数传递方面 ,模块在处理参数之前会对参数进行深度复制,确保不会出现多线程同步问题,模块内部 参数严格定义为只读。变量只局限在方法范围内,完全避免了线程间数据共享。 ![](https://github.com/decaywood/XueQiuSuperSpider/blob/master/info/structure.png) ##优势 * 稳定 对模块内部数据的严格限制保证了无论是如何频繁的多线程操作都不会出现脏读,写覆盖等令人头 疼的并发问题,模块之间无依赖,非常容易进行单元测试,只要模块都通过严格的单元测试, 无论多么复杂的数据搜集以及分析逻辑,雪球超级爬虫都能稳定的工作,运行后不用死死的 盯着日志,安心睡觉。 * 高性能 所有模块顶层实现了Java8的函数式接口,能够依靠Java8的并行流进行高并发操作,用户 可以轻易配置线程池缓存工作线程数量,充分发挥网络IO资源以及CPU资源。 * 极易改造与拓展 散文式的结构决定了雪球超级爬虫是一个可以进行任意拓展的程序,任何人都可以稍作了解 后贡献自己的代码,你甚至可以爬取同花顺网站的数据然后结合东方财富的一些资料,再混合 雪球网站自己数据综合进行分析,你所做的只是添加几个Collector和Mapper而已,很多基础 的模块我已经提供好了。(是不是和Python有点像) ##贡献模块的一些注意事项 * 参数对象请实现DeepCopy接口 对于你定义了在模块间传递的对象,请实现DeepCopy接口,就像我上面提到的,模块间是 不允许共享对象的,模块约定复制传入的参数。 * 对于只读的域变量请定义为final 为了防止你对域的误写,请将域定义为final,这样更加保险 * 完善的单元测试 完成一个模块后,请进行完善的单元测试,包括初始化参数合法性。 输入输出的正确性。 * 具备交换律 特别注意的是,mapper与mapper之间如果输入与输出如果相同,请保证遵守交换律, 即 M1.andThen(M2) equals M2.andThen(M1) * 推荐继承模块模版 每个生命周期对应的接口皆有对应的抽象模板类,他们通过了单元测试,封装了实用的功能, 包括网络请求、Exception捕获,网络IO异常重新请求以及Cookie更新保存等有用的功能, 除非有必要,否则推荐继承模版模块,它们以Abstract开头,支持泛型。 ##一些例子 * 简单的根据关键字获取近期新闻 ```java @Test public void findNewsUcareAbout() { List news = new HuShenNewsRefCollector(HuShenNewsRefCollector.Topic.TOTAL, 2).get(); List res = news.parallelStream().filter(new PageKeyFilter("万孚生物", false)).collect(Collectors.toList()); List regexRes = news.parallelStream().filter(new PageKeyFilter("万孚生物", true)).collect(Collectors.toList()); for (URL re : regexRes) { System.out.println("Regex : " + re); } for (URL re : res) { System.out.println("nonRegex : " + re); } } ``` * 游资追踪 ```java @Test public void LongHuBangTracking() { Calendar calendar = Calendar.getInstance(); calendar.set(2015, Calendar.NOVEMBER, 20); Date from = calendar.getTime(); calendar.set(2015, Calendar.DECEMBER, 1); Date to = calendar.getTime(); DateRangeCollector collector = new DateRangeCollector(from, to); DateToLongHuBangStockMapper mapper = new DateToLongHuBangStockMapper(); StockToLongHuBangMapper mapper1 = new StockToLongHuBangMapper(); List