返回列表 上一主題 發帖

python 融資融券彙總 (全部)"資料

回復 20# lpk187
非常感謝你的分享,內容很棒。
我再來自習一下。

TOP

本帖最後由 c_c_lai 於 2016-9-28 07:05 編輯

回復 1# lpk187
請問大大:
rs.Open('select * from 股票', Conn, 3, 3)
它的意涵為何?
rs.Fields.Item(0).Value = regs[0][n]
rs.Fields.Item(1).Value = regs[1][n]
又為何意?
最近颱風天便抽點時間撰研,謝謝你!

TOP

本帖最後由 lpk187 於 2016-9-28 11:07 編輯

回復 22# c_c_lai


   這是我網路找到的資料 ,給你參考
http://www.asjh.tn.edu.tw/xuploa ... hap02/recordset.htm
Python語法和VBA差不多

而rs.Fields.Item(0).Value = regs[0][n]

rs.Fields.Item(0).Value ==> Fields:        查詢結果中欄位物件的集合, (也就是一個暫存的序列) ,Item(0)序列中第一個項目(也可以用資料表的項目名稱:例如:Item('股票代號'))
regs[0][n] :為爬回的表格的陣列
在這之前有句 rs.AddNew()  也就是新增一列 ,所以rs.Fields 就像是一個一維陣列,既然是一維陣列,所以它還只是一個暫存物件 所以最後,還要rs.Update()才會存入資料庫的資料表中

TOP

回復 23# lpk187
Python 好像無法一行一行 Debug?
所以才會有這麼多的問題,不好意思!
謝謝你的指導!

TOP

回復 24# c_c_lai
pycharm跟visual studio有逐行執行的功能,可以試試看。

TOP

回復 24# c_c_lai

習慣了VBA的區域變數視窗,以及逐步執行來除錯,剛使用python 真的很不習慣,
有時,比如說顯示100行出錯,結果是某一行的變數內容寫錯,真的很不容易除錯
就如 zyzzyva 大大說的,也可以用visual studio來寫,而且功能也蠻多的

TOP

本帖最後由 c_c_lai 於 2016-9-28 17:29 編輯

回復 26# lpk187
回復 25# zyzzyva

真傷腦筋!

TOP

回復 19# c_c_lai

這次是以SQLite3 資料庫寫成的,其用法,和 ADODB有些許的差異,因SQLite3,是python 內建函數,所以不用另裝
其中在資料擷取方面,因擷取下來的資料,有空白 以及 千分位符號 "," 若不處理這些,python 會產生許多錯誤,這些問題也已處理
  1. #-*- coding:utf-8 -*-



  2. import requests
  3. from bs4 import BeautifulSoup
  4. import random
  5. import os
  6. import sqlite3
  7. import datetime
  8. import time

  9. # 隨機更改 headers
  10. def head_random():
  11.       for i in range(10):
  12.             hs = ['Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
  13.                    'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16',
  14.                    'Mozilla/5.0 (Linux; U; Android 4.1.2; zh-tw; GT-I9300 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
  15.                    'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10'
  16.                    'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)']
  17.             hes = {"User-Agent":random.choice(hs)}
  18.       return hes

  19. # 集台證所融資融券餘額全部資料
  20. def read_network_data(date,from_number):
  21.       url = 'http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php'
  22.       head =head_random()
  23.       payload = {"download":'',
  24.                  "qdate":date,
  25.                  "selectType":"ALL"}
  26.       res = requests.post(url, headers=head, data=payload)
  27.       soup=BeautifulSoup(res.text, "lxml")
  28.       tab = soup.select('tbody')[from_number] # 2個表格之2
  29.       regs=[] # 初始陣列
  30.    
  31.       for i in range(len(tab.select('tr')[0].select('td'))): # 定義2維陣列維度
  32.             regs.append([])
  33.       n=0
  34.       for tr in tab.select('tr'): #擷取表格資料
  35.             for i in range(len(tab.select('tr')[0].select('td'))):
  36.                   if n==0 or n==1 or n==15:      #把文字串中的空白文字去除掉
  37.                         strs=tr.select('td')[i].text
  38.                         strs=str(strs.replace(' ',''))
  39.                         regs[i].append(strs)
  40.                   else:    # 把數字中的千分符號 "," 去除掉
  41.                         ints=tr.select('td')[i].text
  42.                         ints=str(ints.replace(',',''))
  43.                         regs[i].append(ints)
  44.                   n +=1
  45.             n=0
  46.       return regs


  47. def check_db_exists(regs):
  48.       if not os.path.exists('twsedata.db'):   # 檢查twsedata.db是否存在(和此程式碼相同的資料夾)
  49.             conn = sqlite3.connect('twsedata.db')  # 如果沒有,就建立一個空白資料庫,(sqlite3.connect) 也是連結語句,有資料庫就連結,沒有就建立
  50.             sql = "CREATE TABLE 股票(股票代號  char(10) PRIMARY KEY,股票名稱  char(20));"
  51.             conn.execute(sql) #在新資料庫建立空白資料表 (股票)
  52.             sql = "CREATE TABLE  融資融券信用交易統計( \
  53.                                                         日期  datetime, \
  54.                                                         項目  char(20), \
  55.                                                         買進 INTEGER, \
  56.                                                         買出 INTEGER, \
  57.                                                         現金(券)償還 INTEGER, \
  58.                                                         前日餘額 INTEGER, \
  59.                                                         今日餘額 INTEGER);"
  60.             conn.execute(sql) #在新資料建立 空白資料表(融資融券信用交易統計)
  61.             conn.commit() # 儲存
  62.             conn.close() #關閉
  63.             
  64.       n=0
  65.       conn = sqlite3.connect('twsedata.db') # conn和上一個 if ..中的 conn是不一樣的 ,上一個是沒有資料庫時才作用,為局部變數而此處,則為以下使用的全局變數
  66.       for i in regs[0]:  #以爬回來的資料陣列的第一列為迴圈
  67.             try:      #先嘗試查詢 i 變數的資料表是否存在,若是不存在會發出 Exception 的錯誤訊息
  68.                   c = conn.cursor()
  69.                   sql = "select * from [" + i + "]"
  70.                   c.execute(sql) # table does not exist
  71.                   c.close()
  72.             except Exception as e:  #當try 發出錯誤訊息(也就是讀不到  i 資料表),此時建立一個 i 資料表
  73.                   c = conn.cursor()
  74.                   sql="CREATE TABLE [" + i + "](日期  DATETIME PRIMARY KEY, \
  75.                                                                               資買進  INTEGER, \
  76.                                                                               資賣出 INTEGER, \
  77.                                                                               資現金償還 INTEGER, \
  78.                                                                               資前日餘額 INTEGER, \
  79.                                                                               資今日餘額 INTEGER, \
  80.                                                                               資限額 INTEGER, \
  81.                                                                               券買進  INTEGER, \
  82.                                                                               券賣出 INTEGER, \
  83.                                                                               券現金償還 INTEGER, \
  84.                                                                               券前日餘額 INTEGER, \
  85.                                                                               券今日餘額 INTEGER, \
  86.                                                                               券限額 INTEGER, \
  87.                                                                               資券互抵 INTEGER, \
  88.                                                                               註記 char(5));"
  89.                   c.execute(sql) #建立 i 資料表
  90.                   sql="INSERT INTO 股票(股票代號, 股票名稱) \
  91.                   VALUES ('" + regs[0][n] + "','" + regs[1][n] + "');"
  92.                   c.execute(sql)  # 在股票資料表中寫入股票代號、股票名稱
  93.                   c.close() # 關閉 c 物件
  94.             n += 1
  95.       conn.commit()
  96.       conn.close()
  97. def add_data(regs,date):
  98.       conn = sqlite3.connect('twsedata.db')
  99.       for i in range(len(regs[0])):
  100.             try: #檢查某日期是否存在於資料表中,當某日期存在時,跳離這次的循環,這裡指的僅是這次,不是跳離 for
  101.                   c = conn.cursor()
  102.                   sql="SELECT * FROM [" + regs[0][i] + "] WHERE 日期 = '" + date + "';"
  103.                   c.execute(sql)
  104.                   c.close()
  105.             except Exception as e: #當日期不存在時,寫入資料到資料表中
  106.                   c = conn.cursor()
  107.                   # 日期格式,在sqlite3中,是以文字型態存入,雖然有提供DATETIME,但非以日期型態存入,日後提出,嗯!需再參閱sqlite3的日期處理
  108.                   
  109.                   sql="INSERT INTO [" + regs[0][i] + "](日期,資買進,資賣出,資現金償還,資前日餘額, \
  110.                                                                                          資今日餘額,資限額,券買進,券賣出,券現金償還, \
  111.                                                                                          券前日餘額,券今日餘額,券限額,資券互抵,註記) \
  112.                                                                        VALUES('" + date + "'," + regs[2][i] + "," + regs[3][i] + ", \
  113.                                                                                           " + regs[4][i] + ",  " + regs[5][i] + "," + regs[6][i] + ", \
  114.                                                                                           " + regs[7][i] + "," + regs[8][i] + ",  " + regs[9][i] + ", \
  115.                                                                                           " + regs[10][i] + "," + regs[11][i] + "," + regs[12][i] + ", \
  116.                                                                                           " + regs[13][i] + "," + regs[14][i]+ ",'" + regs[15][i] + "') ;"
  117.                   c.execute(sql)
  118.                   c.close()
  119.             else:
  120.                    break
  121.       conn.commit()
  122.       conn.close()

  123. # 以下為程式的啟始點:
  124. StartDate=input('請輸入開始擷取日期(西元日期如:2016/1/1):')
  125. EndDate=input('請輸入結束擷取日期(西元日期如:2016/1/31):')
  126. #處理日期還真的很麻煩
  127. ts=time.time()
  128. StartDate = time.strptime(StartDate, "%Y/%m/%d")
  129. EndDate =time.strptime(EndDate, "%Y/%m/%d")
  130. StartDate = datetime.date(StartDate[0], StartDate[1], StartDate[2])
  131. EndDate =  datetime.date(EndDate[0], EndDate[1], EndDate[2])
  132. RangeDate = datetime.timedelta(days = 1)
  133. while StartDate <= EndDate:
  134.       yy,mm,dd=str(StartDate).split('-')
  135.       dat=datetime.datetime(int(yy), int(mm), int(dd))
  136.       dd=dat.strftime('%Y/%m/%d')
  137.       year=str(int(dd[0:4])-1911)
  138.       date=dd.replace(dd[0:4], year)
  139.       print('目前執行網路擷取',date ,'日的資料,請稍後...')
  140.       re=read_network_data(date,1)
  141.       if re[0][0]=='查無資料':
  142.             print(date,'日,可能為休市日,查無資料。')
  143.             StartDate = StartDate + RangeDate
  144.             continue
  145.       print('檢查是否有新股票加入,請稍後...')
  146.       check_db_exists(regs=re)
  147.       print('將資料寫入資料庫中,請稍後...')
  148.       add_data(regs=re,date=dd)
  149.       StartDate = StartDate + RangeDate
  150.       te = time.time()
  151.       print('截至目前,時間已耗費:', int(te - ts),'秒')

  152. print('執行完畢!')
複製代碼

TOP

回復 28# lpk187
測試後結果,如畫面:

我也對改用 Sqlite 3 資料庫感到興趣,
我再來好好研究一番,謝謝你!

TOP

回復 28# lpk187
經檢查資料庫裡的資料錄為零。

TOP

        靜思自在 : 手心向下是助人,手心向上是求人;助人快樂,求人痛苦。
返回列表 上一主題