设为首页 收藏本站
查看: 1500|回复: 0

[经验分享] Python+Selenium实现股票板块数据模拟抓取

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2016-1-11 09:20:00 | 显示全部楼层 |阅读模式
selenium 是一个web的自动化测试工具,支持多平台:windows、linux、MAC ,支持多浏览器:ie、ff、safari、opera、chrome,支持多语言:例如C、JAVA、Python等,支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器的执行,相当于分发机的功能。

虽然Selenium本来是应用于自动化测试领域,但是因为Selenium可以实现Web交互操作,所以可以利用Selenium模拟Web抓取一些常规方式不能抓取的数据,例如一些页面生成后才会动态加载的数据,或者需要登录后才能访问的数据。

下面以获取某股票网站的板块行情数据为例子,介绍Python结合Selenium模拟网页抓取数据的方法:

1、首先配置Python + Selenium环境
(1)访问http://www.python.org/download/去下载合适的python版本,推荐3.4或2.7版本。
QQ截图20160111091827.jpg


(2)安装下载包,一路next。
(3)把python的安装目录添加到path系统变量中即可。
(4)测试python安装是否成功,cmd打开命令行输入 python命令,如下图即成功了
QQ截图20160111091838.jpg

5)安装PIPSetupTools

  安装地址: http://pypi.python.org/pypi/setuptoolshttps://pypi.python.org/pypi/pip


(6)安装Selenium
  执行命令 pip install -U selenium
2、分析其页面结构
   
     页面包括了股票列表和页面列表
QQ截图20160111091844.jpg
QQ截图20160111091905.jpg
股票列表通过id为list-body的ul展示:
QQ截图20160111091913.jpg

页面列表是一个idpage-navidiv,但是这个div是根据股票数据动态生成的。
QQ截图20160111091920.jpg



3、程序逻辑
  通过页面分析,初步的程序逻辑:
        a. 首先通过Selenium的chrome或者firefox驱动加载页面
        b. 通过页面元素抓取数据
        c. 通过Click()方法实现页面跳转
        d. 重复a-c直到页面全部跳转完成  

4、代码实现:
1)获取板块数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'''获取行业板块数据'''
def getIndustrySection():
    __logger.debug("开始:收集行业板块数据")
    try:
        dbOperator = DBOperator()
        dbOperator.connDB()
        table = __stockTables['section']
        date = getNowdate()
        for code in range(1, 100):
            code = '012%03d' % code
            if isStockSectionExitsInDate(table,code, date, dbOperator):
               dataUrl = "http://…………fi_quote_navi_bar&id=bd_ind#mod=list&id=bd%s"% code
               getStockSectionDetail(code,dataUrl,dbOperator)  
         
    except Exception as err:
           __logger.error(">>>>>> Exception: "+str(code) + " " + str(err))
    finally:
        dbOperator.closeDB()
    __logger.debug("结束:收集行业板块数据")




2)抓取代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'''读取信息'''
def getDataFromUrl(dataUrl):
    try:
        browser = webdriver.Firefox()
        browser.get(dataUrl)
        time.sleep(2)
        codes = []
        pages = [1,]
        pageTotalNum = 1
        
        listFoot =browser.find_element_by_class_name("list-foot")
        pageTags =listFoot.find_elements_by_tag_name("a")
        pageTotalNum = len(pageTags) - 2
        
        for i in range(1, pageTotalNum ):
            element =browser.find_element_by_xpath("//ul[contains(@id,'list-body')]")
            codeElements =element.find_elements_by_tag_name("li")
            for codeElement in codeElements:
               codes.append(codeElement.get_attribute("id")[-6:])
            
            listFoot =browser.find_element_by_class_name("list-foot")
            pageTags =listFoot.find_elements_by_tag_name("a")
            nextPage = i + 1
            if i < pageTotalNum and not nextPage in pages:
                pageTags[nextPage].click()
                pages.append(nextPage)
                time.sleep(2)   
        print codes
    except NoSuchElementException as err:
       __logger.error(">>>>>> Exception:  " + str(err))
        return None
    except TimeoutException as err:
       __logger.error(">>>>>> Exception:  " + str(err))
        return None
    except Exception as err:
       __logger.error(">>>>>> Exception:  " + str(err))
        return None
    finally:
        browser.close()
   
    return codes




   3)调用抓取数据并存储数据库
1
2
3
4
5
6
7
8
9
10
11
12
'''获取板块交易信息明细'''
def getStockSectionDetail(sectionCode, dataUrl, dbOperator):
    stockCodes = getDataFromUrl(dataUrl)
        
    if stockCodes == None and len(stockCodes)== 0:
        return False
           
    stockQuotation = {}
    date = getNowDate()
    for stockCode in stockCodes:
        #存储到数据库
        ……






4)多线程实现
    为提高运行效率,采用多线程方式同时采集不同板块数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
threads = []
t1 =threading.Thread(target = getIndustrySection)    #行业板块
t2 =threading.Thread(target = getConceptSection)     #概念板块
t3 =threading.Thread(target = getAreaSection)        #地域板块
threads.append(t1)
threads.append(t2)
threads.append(t3)
  
     
if __name__ =='__main__':
    time1= time.time()
  
    try:
        for t in threads:
           t.setDaemon(True)
           t.start()
     
        while len(threads) > 0 :
            t = threads[0]
            t.join()
            del threads[0]
    except Exception as err:
       __logger.error(">>>>>> Exception: " +str(err))
   
    time2= time.time()
    print "总用时:%d" % (time2-time1)
    __logger.info("总用时:%d" % (time2-time1))





5、数据分析
抓到的数据就可以用作分析了,例如17日板块现金流的情况(当然还要结合其他数据):main为主力流入数据,private为主力流出数据,17日当天只开盘半个小时即熔断,只有煤化工领域录得小幅资金流入:
QQ截图20160111091927.jpg
QQ截图20160111091932.jpg


6、优点和缺点
(1)优点:大多数Web数据都可以采用这种方式获得;
(2)缺点:运行效率较低,加载页面速度慢,如果数据量较大,需要长时间运行,如果是服务端linux,因为没有显示桌面,无法加载firefox或chrome驱动。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-162869-1-1.html 上篇帖子: python通过外部参数发送邮件 下篇帖子: python IO多路复用之select
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表