返回列表 上一主題 發帖

[原創] python上市櫃三大法人買賣超日報資料下載

回復 100# zyzzyva
難怪大家會來使用 Python,光是看其執行能力就足矣。
原來是那麼地簡潔、扼要,又學到了,謝謝你的不吝指導!

TOP

回復 100# zyzzyva
假設不存成 csv,而一一顯示又會是如何處哩,
直截使用 res,好像無動作。(愈來愈喜愛 Python 了)
謝謝囉!

TOP

本帖最後由 koshi0413 於 2016-9-12 20:33 編輯

小弟我終於可以回覆了,感動!!
這文章我追很久了 python 也是看到這篇才開始學的,
在此論壇學了不少vba  也看了些c_c_lai 學到不少,剛好看到c_c_lai有提問,來報答一下
下面為 c_c_lai  之需求,下載csv很方便,也很快!!!  但匯入 SQL麻煩,要在轉碼,故小弟會選擇直接提取(其實是還不會用python直接轉csv碼在自動匯入SQL)
ps:代碼為zyzzyva修改版
pps:源碼中段落有 # 皆為提取網頁時,反覆實驗用,這網頁為了提取所而段落也花了一小時來試各種網頁代碼來用BeautifulSoup提取
  1. # -*- coding: utf-8 -*-
  2. import requests
  3. import time
  4. import os
  5. from bs4 import BeautifulSoup as BS
  6. from datetime import date

  7. headers = {"User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"}
  8. url1 = "等級不夠,網址請自行輸入"
  9. payload = {"download":'',
  10.             "qdate":'105/09/10',
  11.             "selectType":"ALL"}
  12. res = requests.post(url1, headers=headers, data=payload)
  13. #print res.text

  14. soup = BS(res.text)
  15. #print soup.select('.board_trad')[0].text
  16. #tb = soup.select('#main-content')
  17. #print tb
  18. #tb = soup.findAll('table')
  19. soup = soup.select('table')[1]
  20. #print tb
  21. for ta in soup.select('tr')[3:]:
  22.     print ta.select("td")[0].text,ta.select("td")[1].text,ta.select("td")[2].text,ta.select("td")[3].text,ta.select("td")[4].text,ta.select("td")[5].text,ta.select("td")[6].text,ta.select("td")[7].text,ta.select("td")[8].text,ta.select("td")[9].text,ta.select("td")[10].text,ta.select("td")[11].text,ta.select("td")[12].text,ta.select("td")[13].text,ta.select("td")[14].text
複製代碼
這是結果。只po前幾段
0050   元大台灣50       194 104 0 1,056 1,146 194,125 0 5 0 496 501 194,125 19
0051   元大中型100      0 0 0 2 2 4,500 0 0 0 0 0 4,500 0
0052   FB科技           0 0 0 0 0 2,000 0 0 0 0 0 2,000 0
0053   元大電子         0 0 0 0 0 3,247 0 0 0 0 0 3,247 0
0054   元大台商50       0 0 0 0 0 4,656 0 0 0 0 0 4,656 0
0055   元大MSCI金融     20 5 0 622 637 17,163 0 4 0 118 122 17,163 0
0056   元大高股息       7 1 0 94 100 67,508 4 0 0 25 21 67,508 3
0057   FB摩台           0 0 0 0 0 2,006 0 0 0 0 0 2,006 0
0058   FB發達           0 0 0 0 0 1,299 0 0 0 0 0 1,299 0

TOP

回復 103# koshi0413
謝謝你!
我好好地來研究一下。BS(res.text) 我修改成 BS(res.text, 'lxml')
最後之 print( ... ) (因我的版本是 3.5) 我再想想看有沒有更佳的表達處理。
請教 soup.select('table')[1] 為何是 [1]? soup.select('tr')[3:] 的 [3:] 指的又是?
Python 我算是幼兒生,還得向你們請益了。 謝謝囉!

TOP

回復 103# koshi0413
您這麼短的時間已經可以抓到資料了,上手的真快。
用BeautifulSoup會試誤是正常的,我也常常都試好幾次才找到。

TOP

回復 102# c_c_lai
提供另一種方式給您參考(解析網頁後處理資料再存成csv)
  1. import requests
  2. from bs4 import BeautifulSoup
  3. import csv

  4. headers = {"User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"}
  5.            
  6. url = 'http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php'

  7. myDate = '105/09/08'

  8. payload={'download':'',
  9.         'qdate':myDate,
  10.         'selectType':'ALL'}

  11. res = requests.post(url, headers=headers, data=payload)
  12. soup = BeautifulSoup(res.text, 'lxml')

  13. trs = soup.select('table tr')

  14. myList = []
  15. subList = []

  16. header1 = ['股票代號','股票名稱','融資(單位: 交易單位)','','','','','',
  17.             '融券(單位: 交易單位)','','','','','','資券互抵','註記']

  18. header2 = ['','','買進','賣出','現金償還','前日餘額','今日餘額','限額',
  19.             '買進','賣出','現金償還','前日餘額','今日餘額','限額','','']

  20. for i, tr in enumerate(trs):
  21.     if i == 6:
  22.         subList = header1
  23.     elif i == 7:
  24.         subList = header2
  25.     else:
  26.         for td in tr.find_all('td'):
  27.             subList.append(td.text)
  28.    
  29.     myList.append(subList)
  30.     subList = []
  31.     if i == 5:
  32.         myList.append(subList)

  33. with open('output.csv', 'w', new='', encoding='utf-8') as f:
  34.     f.write('\ufeff')
  35.     w = csv.writer(f)
  36.     for sub in myList:
  37.         w.writerow(sub)
複製代碼
如果不求美觀,可以直接用pandas:
  1. import requests
  2. import pandas as pd

  3. headers = {"User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"}
  4.            
  5. url = 'http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php'

  6. myDate = '105/09/07'

  7. payload={'download':'',
  8.         'qdate':myDate,
  9.         'selectType':'ALL'}

  10. res = requests.post(url, headers=headers, data=payload)

  11. dfs = pd.read_html(res.text)

  12. #在ipython,dfs[1]就可以取出主要的資料
  13. dfs[1]
複製代碼

TOP

回復 104# c_c_lai

soup.select('table')[1] 為何是 [1]?
網頁代碼中,取第二個'table'

soup.select('tr')[3:] 的 [3:]
網頁代碼中,取第三個'tr'

第一、二個為標題,小弟直接匯入sql,所以不需要這二項目,所以沒提取~~
z大有最新回文,他的代碼比較正確,小弟的代碼都是簡易型的,只要取到資料能導入sql即可

TOP

對了   個人覺的這段可以像vba一樣用 i = 1 to 14 來迴圈表示
只是還不會用

for ta in soup.select('tr')[3:]:
    print ta.select("td")[0].text,ta.select("td")[1].text,ta.select("td")[2].text,ta.select("td")[3].text,ta.select("td")[4].text,ta.select("td")[5].text,ta.select("td")[6].text,ta.select("td")[7].text,ta.select("td")[8].text,ta.select("td")[9].text,ta.select("td")[10].text,ta.select("td")[11].text,ta.select("td")[12].text,ta.select("td")[13].text,ta.select("td")[14].text

TOP

本帖最後由 lpk187 於 2016-9-12 23:46 編輯

回復 103# koshi0413

看來熱衷於python 的同好在這討論區,也蠻多人的
python 的io可以輸出很多格式,csv .xlsx甚至sql都行

當C大開始討論這網址 http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php
就在想,表格還是交給表格專家 pandas 來處理,於是借了你大部份代碼來做看看,效果還不錯
  1. import requests
  2. from bs4 import BeautifulSoup
  3. import pandas as pd
  4. import io

  5. url = 'http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php'
  6. headers = {"User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"}
  7. url1 = "http://www.twse.com.tw/ch/trading/exchange/MI_MARGN/MI_MARGN.php"
  8. payload = {"download":'',
  9.             "qdate":'105/09/10',
  10.             "selectType":"ALL"}
  11. res = requests.post(url1, headers=headers, data=payload)
  12. tbl=pd.read_html(res.text)

  13. deta=tbl[1]
  14. deta.columns = ['股票代號','股票名稱','買進','賣出','現金償還','前日餘額','今日餘額','限額','買進','賣出','現券償還','前日餘額','今日餘額','限額','資券互抵','註記']
  15. deta.to_csv('test1.csv')
複製代碼

TOP

本帖最後由 c_c_lai 於 2016-9-13 08:42 編輯

回復 106# zyzzyva
回復 109# lpk187
回復 107# koshi0413
zyzzyva 大大, 感激不盡!
還是老問題 , with open('output.csv', 'w', new='', encoding='utf-8') as f: 的
new 真的需要改成 with open('output.csv', 'w', "new"='', encoding='utf-8') as f:
"new" ( 打不出來) 才行。
koshi0413 大大,
我發現這兒使用 pandas 顯示結果雖稍稍耗時,但成果是很漂亮。(很值得參考應用)
#在ipython,dfs[1]就可以取出主要的資料
#dfs[1]
#dfs       #類似 103樓 的結果 (差異點:一個是使用 pandas,另一是應用 BeautifulSoup 處理)
lpk187 大大 ,   
#109樓之解題結果與 100樓 的解答類似,雖第一欄加入了 Counter,但過程使用較多的套件。
我發現使用 requests.post(url, headers=headers, data=payload, stream=True) 不需像 pandas
需菱形加入 deta.columns = ['] 等動作。在 tbl=pd.read_html(res.text) 時,它不會自動帶入嗎?

看了三位的不同佳作,才深深覺得我對 Python 之認識初淺,實在太感謝三位能從不同的角度來探討
共同主題,如此學習者才能深切體會、領受,再次謝謝,這亦是我為何喜愛這個論壇的原因。

TOP

        靜思自在 : 【行善要及時】行善要及時,功德要持續。如燒開水一般,未燒開之前千萬不要停熄火候,否則重來就太費事了。
返回列表 上一主題