美文网首页java收集程序员Java学习笔记
利用JAVA+phantomjs爬取深交所互动易股票数据(翻页:

利用JAVA+phantomjs爬取深交所互动易股票数据(翻页:

作者: MusicManCJ | 来源:发表于2016-12-10 20:43 被阅读894次

    目标

    爬取深交所互动易一个论坛型的网站

    http://irm.cninfo.com.cn/szse/index.html

    爬取各公司股票代码中的问答,筛选所有问答中有关于时间+入股人数

    截取目标

    输出格式为 0|股票代码|日期|人数

    分析URL

    这个是各个公司股票的主页

    http://irm.cninfo.com.cn/ssessgs/S000019/index.html

    其中000019是股票代码,也是唯一的,指的是各个公司,可以通过这个来变更。
    需要抓取全部回答,发现有个更多按钮,点击进入

    http://irm.cninfo.com.cn/ircs/interaction/lastRepliesforSzseSsgs.do?condition.type=1&condition.stockcode=000019&condition.stocktype=S

    这个就是最终需要抓取的页面了,000019就是唯一股票代码

    最终抓取页面

    看了下底部分页

    分页

    点击第二页,观察URL

    http://irm.cninfo.com.cn/ircs/interaction/lastRepliesforSzseSsgs.do?condition.type=1&condition.stockcode=000019&condition.stocktype=S

    What?

    点击分页URL居然没变化,这就纳闷了,分析了下js

    js

    原来是直接改变input值直接form表单提交,分析了分页原理后,想到了phantomjs可以直接操作js
    欣赏了下官方例子引入JQuery

    https://github.com/ariya/phantomjs/blob/master/examples/phantomwebintro.js

    于是写了hdy.js:(引入的jq是百度公共资源 http://cdn.code.baidu.com/

    //获取页面回答
    system = require('system');
    var page = require('webpage').create();
    var url = system.args[1];
    
    page.open(url, function(status) {
        if(status == 'success') {
            //引入JQuery,操作元素
            page.includeJs("http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js", function() {
                page.evaluate(function() {
                    //模拟提交表单切换到第二页
                    $("#pageNo").val(2);
                    $("#form1").submit();
                });
            });
    
            window.setTimeout(function() {
                console.log(page.content);
                phantom.exit(0);
            }, 1000);
        } else {
            phantom.exit(1);
        }
    });
    

    执行

    关于如何执行可参考本人上一篇文章:如何用JAVA爬取AJAX加载后的页面(利用phantomjs) http://www.jianshu.com/p/96220e239c35

    如果不引入jQuery也可以,直接用

    page.evaluate(function() { 
        document.getElementById('pageNo').value = '2';  
        document.getElementById("form1").submit();
    }); 
    

    只不过本人习惯用jq,引入jq操作dom比较熟练
    执行打印出结果为第二页的页面,完美。

    循环获取所有页面

    循环获取所有页面只要取到总页数,再遍历即可,再次打开Chrome开发者工具,看下元素

    分页

    红色框中为需要得到的元素,未发现有class或id可直接用,分析发现最后一页总是倒数第二个a标签,最后一个是右箭头跳转下一页,于是还是同样的方法,写hdy-getPage.js,

    //获取总页数
    system = require('system');
    var page = require('webpage').create();
    var url = system.args[1];
    
    page.open(url, function(status) {
        if(status == 'success') {
            page.includeJs("http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js", function() {
                num = page.evaluate(function() {
                    return $('.PagesBox a:last-child').prev('a').text();
                });
            });
    
            window.setTimeout(function() {
                console.log(num);
                phantom.exit(0);
            }, 1000);
        } else {
            phantom.exit(1);
        }
    });
    

    获取了总页数之后,剩下就是把hdy-getPage.js获取的页数传进hdy.js了,试了下

    //获取页面回答
    system = require('system');
    var page = require('webpage').create();
    var url = system.args[1];
    var pageNum = system.args[2];//执行语句传入参数
    
    page.open(url, function(status) {
        if(status == 'success') {
            page.includeJs("http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js", function() {
                page.evaluate(function() {
                    $("#pageNo").val(pageNum);
                    $("#form1").submit();
                });
            });
    
            window.setTimeout(function() {
                console.log(page.content);
                phantom.exit(0);
            }, 1000);
        } else {
            phantom.exit(1);
        }
    });
    

    嗯,自我感觉良好,执行!

    出现错误!! ReferenceError: Can't find variable: pageNum

    什么,作为全局变量无法传入page.evaluate方法?

    解决

    解决方案 https://zhidao.baidu.com/question/498148919297194004.html

    已经写得很清楚了,需要作为参数传入

    修改了hdy-getPage.js

    //获取页面回答
    system = require('system');
    var page = require('webpage').create();
    var url = system.args[1];
    var pageNum = system.args[2];//执行语句传入参数
    
    page.open(url, function(status) {
        if(status == 'success') {
            page.includeJs("http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js", function() {
                page.evaluate(function(pageNum) {//传入参数
                    $("#pageNo").val(pageNum);
                    $("#form1").submit();
                }, pageNum);//参数值
            });
    
            window.setTimeout(function() {
                console.log(page.content);
                phantom.exit(0);
            }, 1000);
        } else {
            phantom.exit(1);
        }
    });
    

    执行了下,确实没有报错,想要的页面也打印出来了。

    关于如何利用JAVA来执行phantomjs,可参考上一篇文章。
    至于pageNum如何传入,同理在执行语句增加一个参数即可,注意空格

    /Users/music-man/Downloads/phantomjs/phantomjs /Users/music-man/Downloads/phantomjs/hdy.js 爬取页面url 页码
    

    爬取出页面后得到回答


    爬取结果

    分析需要的回答可能出现的情况,利用正则匹配所需要的内容

    你好,谢谢你的关注,截至2016年11月30日,本公司A、B股股东人数合计130,071户。
    您好!截至11月30日的股东人数为12554,谢谢!
    尊敬的投资者,您好!截至2016年11月30日,公司的股东总户数为104,154户,谢谢。
    截至2016年11月30日,公司股东截至2016年11月30日总数为167,135,其中,A股股东总数为124,738, B股股东总数为42,397。多谢
    你好,谢谢你的关注,截至2016年11月15日,本公司A、B股股东人数合计131,212户。
    截止9月30日,公司股东户数为82,454户,后续股东户数请关注公司下期定期报告。
    您好!截至2016年9月30日,公司股东户数是48,621;截至2016年10月14日,公司股东户数是48,481。
    您好!截至2016年9月14日,公司股东户数是48382。公司未获悉大股东增持计划。
    您好!截至2016年8月15日,公司股东户数是49,228。
    您好!截至7月31日,公司股东户数是52735。
    2016年11月30日,公司股东户数为36294。
    您好,感谢您对飞亚达公司的关注!截至11月30日,公司A股股东人数为25977人。谢谢!
    至11月30日,公司股东总户数为64,183。谢谢您的关注!
    您好。截至2016年11月30日,公司股东总户数为11,602户。
    投资者您好,谢谢您对公司的关注。截止2016年8月底,公司股东总户数121,806户。如有其他问题,欢迎致电公司投资者咨询专线010-66573955。
    截止于9月30日,公司共有股东:21539人。感谢你对我公司的关注,谢谢!
    投资者,您好。截至2016年11月30日,公司股东总户数33318户。感谢您对公司的关注。
    感谢您的关注,根据中登公司深圳分公司提供的数据,截至11月30日,公司在册股东总人数为:46343人。
    

    这是需要在所有回答中匹配出来的结果,在这里推荐一个匹配正则的网站

    http://www.regexr.com/ 可以实时显示匹配

    正则匹配
    正则表达式(可能还没考虑周全,如有更好的方案非常欢迎拍砖!)

    \d+月\d+日.(数|股).\d[,|.|\。|\,|人|户]

    由于还需要一个年份,发现每一个回答有创建时间


    可以利用,截取拼接在匹配到的数据前面,再经过切割,正则匹配,最终可以得到:年份+股东数的格式,细节可以自由发挥了。

    Swing界面

    (2017年12月05日 涉及隐私删除掉好了)

    最终得到所需要的数据格式,并输出文件。

    转载请注明出处,若本文对您有重大帮助,非常欢迎打赏,这将激励我更好的创作,谢谢

    相关文章

      网友评论

      • 灵魂放逐:用nodejs的phantom模块会更好,已经可以用async/await了
      • 92944c550535:你好,你的phantomjs爬虫软件成熟了吗?可以分享一个我体验?1403113@qq.com

      本文标题:利用JAVA+phantomjs爬取深交所互动易股票数据(翻页:

      本文链接:https://www.haomeiwen.com/subject/fvrumttx.html