Python+Selenium實現股票板塊數據模擬抓取


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版本。

wKioL1aPi3mhkeQqAAFPb2WSTrM808.png

 

 

2)安裝下載包,一路next。

 

3)把python的安裝目錄添加到path系統變量中即可。

 

4)測試python安裝是否成功,cmd打開命令行輸入 python命令,如下圖即成功了

wKioL1aPi9Syuu0kAAAe3hPOIsg788.png

 

 

5)安裝PIPSetupTools

 

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

 

 

(6)安裝Selenium

  執行命令 pip install -U selenium

 

2、分析其頁面結構

   

     頁面包括了股票列表和頁面列表

 wKioL1aPi-rADll2AAD52dLVJgQ222.png

wKioL1aPjEThJwQTAABjjm7rsCU934.png

股票列表通過id爲list-body的ul展示:

 wKiom1aPi8yB8e2zAABUTQOMa9E373.png


頁面列表是一個idpage-navidiv,但是這個div是根據股票數據動態生成的。

wKiom1aPi9uClSLgAAAzS2CBEKQ699.png

 

 

 

3、程序邏輯

  通過頁面分析,初步的程序邏輯:

        a. 首先通過Selenium的chrome或者firefox驅動加載頁面

        b. 通過頁面元素抓取數據

        c. 通過Click()方法實現頁面跳轉

        d. 重複a-c直到頁面全部跳轉完成 

 

4、代碼實現:

1)獲取板塊數據

'''獲取行業板塊數據'''
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)抓取代碼

 

'''讀取信息'''
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)調用抓取數據並存儲數據庫

'''獲取板塊交易信息明細'''
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)多線程實現

    爲提高運行效率,採用多線程方式同時採集不同板塊數據:

 

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日當天只開盤半個小時即熔斷,只有煤化工領域錄得小幅資金流入:

 wKiom1aPj26zvLJgAACeMX0cLbc120.png

wKiom1aPjUfggjxnAAAkTbf6Fjk745.png

 

 

6、優點和缺點

(1)優點:大多數Web數據都可以採用這種方式獲得;

(2)缺點:運行效率較低,加載頁面速度慢,如果數據量較大,需要長時間運行,如果是服務端linux,因爲沒有顯示桌面,無法加載firefox或chrome驅動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章