返回列表 上一主題 發帖

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

回復 79# c_c_lai
怪怪,我的可以說,您的在ipython裡可以顯示可是用筆記本開反而不行?
編碼的問題我也一直很頭痛,會用utf-8是因為資料裡有一些不是big5,像「平瀬義樹 牧師」的「瀬」。
在最後with open那邊的encoding改成encoding='utf-8-sig'試試看。

TOP

回復 81# c_c_lai

我的是能正常顯示,可能是系統還是那邊的問題,有點事得出門,明天再找別台電腦測看看。

TOP

回復 83# c_c_lai
後面那段我能理解,是excel讀取csv預設編碼的問題,2007以後的版本應該寫入BOM(byte of mark)可以解決。
之前在encoding=utf-8後面加上sig就是加上BOM,不知道為什麼在2010不行。您有空的話再試試看把他改回去utf-8,
然後在下面加一行「f.write('\ufeff')」手動寫入試試看。
前面那段的問題我實在想不出原因,抓下來的資料在筆記本裡有時正常有時亂碼?
有沒有辦法複製錯誤?確認是不是特定情況或是頁面會出現亂碼的問題,這樣比較有個方向。
pandas就我所知主要用在後段的資料分析,準備資料通常應該還是需要其他工具輔助。

TOP

回復 90# c_c_lai
太好了!如果這樣也不行就頭痛了。
原文中有提到希望可以用縣市為單位來抓。因為網站本身就有提供縣市別分類的連結,如:
http://church.oursweb.net/slocation.php?w=1&c=TW&a=台中市&t=
其實只要把連結換一下,總頁數改一下用現有的 code就可以把該區域的資料抓下來了。
但如果要讓使用者選擇呢?假設我們已經依使用者選擇進入該分區的頁面,但是要如何決定總頁數呢?
以台中市來說。 Screenshot_1.png ,能把圖裡藍圈中的31抓出來嗎?

TOP

回復 92# c_c_lai
說指導不敢當,我也是趁這個機會一邊做一邊學。
其實好不好抓跟網頁的html編排有很大的關係,會提這個數字是因為我自己試了覺得這個數字還有點小麻煩。

您如果是用chrome,可以在想抓取的資料上按右鍵,選「檢查」,應該可以看到類似圖中的畫面(有時候需要點開樹狀結構)。
以這個結構來說,除了上面table的class="tb_pages",我沒有看到什麼容易用的東西,所以我會選這個table做為起始的參考點。
(通常找到目標的方式都會有非常多種,只要能找得到就好了),用下面的code就可以找到整個句子:
  1. url = 'http://church.oursweb.net/slocation.php?w=1&c=TW&a=台中市&t='

  2. res = requests.get(url)

  3. res.encoding='utf-8'

  4. soup = BeautifulSoup(res.text, 'lxml')

  5. target = soup.select('.tb_pages td')[0].text

  6. print(target)
複製代碼
但是數字還是藏在裡頭,真是有點煩人。
到這邊我是再用regular expression把它取出來。
  1. import re
  2. total_num = re.search(r'/\s\d{1,3}', target).group().replace('/ ','')
  3. print(total_num)
複製代碼
另一個比較簡單的方式則是用lxml。

TOP

剛想了一下,以這個頁面來說,其實也不用用到BeautifulSoup,直接用re就可以了。
  1. import requests
  2. import re

  3. url = 'http://church.oursweb.net/slocation.php?w=1&c=TW&a=台中市&t='

  4. res = requests.get(url)

  5. total_num = re.findall(r'/\s\d{1,3}', res.text)[0].replace('/ ','')

  6. print(total_num)
複製代碼

TOP

回復 95# clianghot546
要看你是要什麼樣的結果。需要做那些處理。如果要做一些一般的運算我都還是會放到excel裡。
雖然理論上python也有很多套件可以做各種分析,不過一般使用來說,我還是覺得excel的工作表跟儲存格比較親切。

TOP

回復 96# c_c_lai
r'/\s\d{1,3}':字串前面加上r是表示raw string,就是通知python不要理會特殊字元,照字串原本的樣子代進去re module。
後面就是re的表示,以「總共 5704 筆資料 《《上一頁 頁次 1 / 286 下一頁》》」來說, 「/」就是在兩個數字(1、286)之間
「/」之後有一個空白(在re裡就是「\s」,後面「\d」表示數字,「{1,3}」表示有1~3個前面的東西(以這裡來說就是「\d」。
BeautifulSoup不一定要用lxml做為parser,網頁如果結構良好,用那種差別其實不大(lxml速度可能好一些)。
可以參考https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#id49
soup.select('.tb_pages td')返回的是一個list,list[0]就是list的第一個元素的意思。
regular expression的速度滿好的,應該各語言都有相應的模組,不過我比較少用,一個是不熟,一個是pattern比較廣的時候,怕會比對到意料外的資料。
python不會知道那是總頁數,還是要靠人觀察,python只能知道某個位子(或符合re pattern)的數字是什麼。

TOP

回復 99# c_c_lai
這個有提供csv下載阿,用我們這個討論串開頭的方式直接抓csv應該是最快的。
  1. import requests

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

  5. payload={'download':'csv',
  6.         'qdate':'105/09/07',
  7.         'selectType':'ALL'}

  8. res = requests.post(url, headers=headers, data=payload, stream=True)

  9. with open('test.csv', 'wb',) as f:
  10.     for chunk in res.iter_content(1024):
  11.         f.write(chunk)
複製代碼

TOP

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

TOP

        靜思自在 : 有智慧才能分辨善惡邪正;有謙虛才能建立美滿人生。
返回列表 上一主題