2019年7月27日 星期六

Python 3 + Google 新聞爬蟲 + 罔拍 MONPA 中文正體分詞

import requests
from bs4 import BeautifulSoup
import monpa

res = requests.get("https://news.google.com.tw")
soup = BeautifulSoup(res.text)

count = 1
for item in soup.select(".MQsxIb"):
    print('=====[',count,']=====')
    news_title = item.select(".ipQwMb")[0].text
    news_url = item.select(".ipQwMb")[0].find('a')['href']
    print(news_title)
    result = monpa.pseg(news_title)
    for t in result:
        print(t)
    count+=1
    #print(news_url)
執行結果:
=====[ 1 ]=====
國安私菸案》檢調大搜索華航總部 歷時9小時公關室也沒放過
['國安', 'ORG']
['私菸案', 'Na']
['》', 'PARENTHESISCATEGORY']
['檢調', 'Na']
['大', 'VH']
['搜索', 'VC']
['華航', 'ORG']
['總部', 'Nc']
[' ', 'D']
['歷時', 'VJ']
['9', 'Neu']
['小時', 'Nf']
['公關室', 'Nc']
['也', 'D']
['沒', 'D']
['放過', 'VC']
=====[ 2 ]=====
快訊/國安局私菸事件華航首波懲處拔官名單出爐| 交通氣象
['快訊', 'Na']
['/', 'PERIODCATEGORY']
['國安局', 'ORG']
['私菸', 'VA']
['事件', 'Na']
['華航', 'ORG']
['首', 'Nes']
['波', 'Nf']
['懲處', 'Nv']
['拔官', 'Na']
['名單', 'Na']
['出爐', 'VH']
['|', 'FW']
[' ', 'VC']
['交通', 'Na']
['氣象', 'Na']
=====[ 3 ]=====
國安私菸案》吳宗憲傳致電黃川禎:我訂那麼多 華航高層知道嗎
['國安', 'Nb']
['私菸案', 'Na']
['》', 'PARENTHESISCATEGORY']
['吳宗憲', 'PER']
['傳', 'VD']
['致電', 'VC']
['黃川禎', 'PER']
[':', 'COLONCATEGORY']
['我', 'Nh']
['訂', 'VC']
['那麼多', 'Neqa']
[' 華航', 'PER']
['高層', 'Na']
['知道', 'VK']
['嗎', 'T']
=====[ 4 ]=====
華航公布14次專機負責人!開鍘羅雅美、邱彰信
['華航', 'PER']
['公布', 'VE']
['14', 'Neu']
['次', 'Nf']
['專機', 'Na']
['負責人', 'Na']
['!', 'EXCLAMATIONCATEGORY']
['開', 'VC']
['鍘羅雅美', 'PER']
['、', 'PAUSECATEGORY']
['邱彰信', 'PER']
=====[ 5 ]=====
華航開鍘!公布14次專機負責人羅雅美邱彰信調非主管職| 政治
['華航', 'PER']
['開鍘', 'Na']
['!', 'EXCLAMATIONCATEGORY']
['公布', 'VE']
['14', 'Neu']
['次', 'Nf']
['專機', 'Na']
['負責人', 'Na']
['羅雅美', 'PER']
['邱彰信調', 'PER']
['非', 'VG']
['主管', 'Na']
['職', 'Na']
['|', 'FW']
[' 政治', 'PER']
=====[ 6 ]=====
只是賣太多菸?他揭華航最大漏洞
['只是', 'D']
['賣', 'VD']
['太多', 'Neqa']
['菸', 'Na']
['?', 'QUESTIONCATEGORY']
['他', 'Nh']
['揭', 'VC']
['華航', 'ORG']
['最', 'Dfa']
['大', 'VH']
['漏洞', 'Na']
=====[ 7 ]=====
黃國昌揭私菸案 洪慈庸:綠支持者問「這樣好嗎?」
['黃國昌', 'PER']
['揭', 'VC']
['私菸案', 'Na']
[' 洪慈庸', 'PER']
[':', 'COLONCATEGORY']
['綠', 'VH']
['支持', 'VC']
['者', 'Na']
['問', 'VE']
['「', 'PARENTHESISCATEGORY']
['這樣', 'VH']
['好', 'VH']
['嗎', 'T']
['?', 'QUESTIONCATEGORY']
['」', 'PARENTHESISCATEGORY']
=====[ 8 ]=====
時力分裂?黨內同志要約黃國昌見面 結果是......
['時力', 'Na']
['分裂', 'VHC']
['?', 'QUESTIONCATEGORY']
['黨內', 'Nc']
['同志', 'Na']
['要', 'D']
['約', 'VC']
['黃國昌', 'PER']
['見面 ', 'Na']
['結果', 'Na']
['是', 'SHI']
['......', 'ETCCATEGORY']
=====[ 9 ]=====
內鬨?洪慈庸:綠基層焦慮黃國昌:追弊案不可看顏色
['內鬨', 'Na']
['?', 'QUESTIONCATEGORY']
['洪慈庸', 'PER']
[':', 'COLONCATEGORY']
['綠', 'VH']
['基層', 'A']
['焦慮', 'Nv']
['黃國昌', 'PER']
[':', 'COLONCATEGORY']
['追', 'VC']
['弊案', 'Na']
['不可', 'D']
['看', 'VC']
['顏色', 'Na']

2019年4月30日 星期二

python 抓取上市及上櫃公司清單, 並寫入 MySQL 資料庫

不囉嗦,直接看程式碼:
# 如何獲得上市上櫃股票清單
import requests
import time
import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy.types import NVARCHAR, Date

def getTWSE(str_mode):
     # 設定爬蟲程式的 User_Agent
    headers = {'user-agent': 'Mozilla/5.0 (Macintosh Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
    # 上市: http://isin.twse.com.tw/isin/C_public.jsp?strMode=2
    # 上櫃: http://isin.twse.com.tw/isin/C_public.jsp?strMode=4
    req_url = "http://isin.twse.com.tw/isin/C_public.jsp?strMode=%s" % (str_mode)
    res = requests.get(req_url, headers=headers)
    df = pd.read_html(res.text)[0]

    # 設定column名稱
    df.columns = df.iloc[0]
    # 刪除第一行
    df = df.iloc[1:]
    # 先移除row,再移除column,超過三個NaN則移除
    df = df.dropna(thresh=3, axis=0).dropna(thresh=3, axis=1)
    df[['有價證券代號','名稱']] = df['有價證券代號及名稱'].str.split(n=1, expand=True)
    del df['有價證券代號及名稱']
    df = df.set_index('有價證券代號')
    return df

engine = create_engine("mysql+pymysql://stockuser:password@127.0.0.1:3306/stockdb")

dtypedict = {
    '有價證券代號':NVARCHAR(length=32),
    '上市日': Date()
}

# 抓取上市公司股票清單, 寫入MySQL > stockdb > listed_code (listed_code table存在時整個取代)
listed_companies = "2"  #上市公司
mydf1 = getTWSE(listed_companies)
mydf1.to_sql(name="listed_code", con=engine, if_exists = 'replace', index=True, dtype=dtypedict)

# 先睡個10秒鐘吧
time.sleep(10)

# 抓取上櫃公司股票清單, 寫入MySQL > stockdb > listed_code (append 到 listed_code table)
listed_companies = "4" #上櫃公司
mydf2 = getTWSE(listed_companies)
mydf2.to_sql(name="listed_code", con=engine, if_exists = 'append', index=True, dtype=dtypedict)

2019年4月29日 星期一

python 讀取 MySQL 資料

sqlalchemy連結MySQL時,必須先安裝另一模組 pymysql
pip install pymysql
接下來利用 python 來讀取先前我們用R寫入的股價資料庫
%matplotlib inline

import pandas as pd
from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://stockuser:password@127.0.0.1:3306/stockdb")

sql ="select * from tw1101;"

df = pd.read_sql_query(sql, engine)

print(df)

df.close.plot()
執行結果:
  row_names        date       open       high        low      close  \
0            1  2009-01-02  24.193001  24.193001  24.193001  24.193001   
1            2  2009-01-05  25.135599  25.225300  24.597000  24.821400   
2            3  2009-01-06  24.955999  25.135599  24.372499  24.641800   
3            4  2009-01-07  25.090700  25.449800  24.417400  25.225300   
4            5  2009-01-08  24.372499  24.731600  23.789000  24.417400   
5            6  2009-01-09  24.552099  25.090700  23.789000  23.789000   
...
          volume   adjusted  
0            0.0  14.254436  
1     22712510.0  14.624688  
2     20298561.0  14.518868  
3     26370751.0  14.862664  
4     23748492.0  14.386651
...
2536  30751985.0  41.000000  
2537  23165336.0  41.599998  
2538  16390191.0  41.549999  
2539  13459252.0  41.799999  
2540  11300709.0  41.750000  

[2541 rows x 8 columns]

2019年4月28日 星期日

R tidyquant 抓取股價資料寫入 MySQL 資料庫

MySQL上先建立一個新使用者 stockuser :
mysql -u root -p
出現 mysql > 後,開始建立新用者資料並設定密碼:
mysql >
mysql > GRANT ALL PRIVILEGES ON *.* TO 'stockuser'@'%' IDENTIFIED BY 'password';
mysql > FLUSH PRIVILEGES;
mysql > quit;
若MySQL伺服器要開放遠端連結,記得防火牆允入3306埠,另外 MySQL的設定檔也要檢查:
vi /etc/mysql/my.cnf
記得 bind-address = 127.0.0.1 這行要註解
#bind-address           = 127.0.0.1
也記得 MySQL 要重新啟動
service mysql restart
資料庫部分沒問題的話,就可以準備來使用R抓取股價資料~R 如果還沒有安裝過 RMySQL package, 也記得先安裝:
install.packages("RMySQL")
確認安裝完成後,就開始吧...
library(RMySQL)

library(DBI)
library(tidyquant)
library(dplyr)

cn <- dbConnect(
 drv = RMySQL::MySQL(),
 username='stockuser',
 password='password',
 host='127.0.0.1',
 port = 3306,
 dbname = "stockdb"
 )

#  利用 tidyquant 取得 Yahoo 上的台灣五十股價資料, 寫入 MySQL stockdb > tw{股票代碼}
tw50 <- c("1101","1102","1216") #只有示範三檔股票
for (i in tw50) {
 stockid <- paste(i,"TW",sep=".")
 tblname <- paste("tw",i,sep="")
 print(stockid)
 sdata <- tq_get(stockid)
 dbWriteTable(cn, name=tblname, value=sdata, overwrite=TRUE)
 Sys.sleep(10) # 每次 Loop 先休息 10 秒
}

# 利用 tidyquant 取得 Yahoo 上的IBM股價資料, 寫入 MySQL stockdb > ibm
ibm <- tq_get("IBM")
dbWriteTable(cn, name="ibm", value=ibm, overwrite=TRUE)

dbDisconnect(cn) #記得斷開資料庫連線
資料都抓取完成後,MySQL資料庫裡面 stockdb > 就會多個股 table :
mysql -u stockuser -p
輸入密碼,登入後...
mysql> use stockdb;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_stockdb |
+-------------------+
| ibm               |
| tw1101            |
| tw1102            |
| tw1216            |
+-------------------+
4 rows in set (0.00 sec)
以後就可以直接從 MySQL 中讀取股價資料來運用:
# 從 MySQL 取出 IBM 股價資料
cn <- src_mysql(
 user='stockuser',
 password='password',
 host='127.0.0.1',
 port = 3306,
 dbname = "stockdb"
 )

ibm_table <- tbl(cn, "ibm")
ibm_table

dbDisconnect(cn)
延伸閱讀資料:
  • Amazon RDS + R (其實我是租不起, 所以自建 MySQL...)
  • R學習筆記 - 資料工程篇(四) Database


  • 2018年11月14日 星期三

    ubuntu 7-zip 安裝與使用

    安裝指令
    sudo apt-get install p7zip-full
    

    執行壓縮: 7z a 壓縮檔案 目標來源
    7z a demo.7z demo_path_or_file
    

    執行加密壓縮: 7z a 壓縮檔案 目標來源 -p加密密碼
    7z a demo.7zp demo_path_or_file -pMYPASSWD
    

    執行密碼解壓縮: 7z x 壓縮檔案 -p加密密碼
    7z x demo.7zp -pMYPASSWD
    

    2018年10月19日 星期五

    2018年4月1日 星期日

    把 IPython notebook貼上Blogger文章上分享

    In [1]:
    import win32com.client
    import time
    
    xlApp = win32com.client.Dispatch("Excel.Application")
    xlApp.Visible=1
    
    workBook = xlApp.Workbooks.Open(r"C:\Users\kenne\Desktop\datelist.xlsx")
    print(str(workBook.ActiveSheet.Cells(1,1)))
    now = time.time()
    workBook.ActiveSheet.Cells(1, 2).Value = now
    #SaveChanges = 1 : Save flle
    # SaveChanges = 0 : Nothing Saved
    workBook.Close(SaveChanges=1)
    xlApp.Quit()
    
    參考此篇(How to quickly turn an IPython notebook into a blog post)",將 .ipynb 轉成 HTML code
    !ipython nbconvert --to html --template basic filename.ipynb
    
    接下來就把目錄底下的 filename.html 檔案內的HTML原碼貼上 blogger.com ,然後記得在HTML原碼前面加上底下的CSS碼,就可以囉~
    <style type="text/css">
    .highlight{background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .1em;padding:0em .5em;border-radius: 4px;}
    .k{color: #338822; font-weight: bold;}
    .kn{color: #338822; font-weight: bold;}
    .mi{color: #000000;}
    .o{color: #000000;}
    .ow{color: #BA22FF;  font-weight: bold;}
    .nb{color: #338822;}
    .n{color: #000000;}
    .s{color: #cc2222;}
    .se{color: #cc2222; font-weight: bold;}
    .si{color: #C06688; font-weight: bold;}
    .nn{color: #4D00FF; font-weight: bold;}
    </style>
    

    同場加映補充資料:HTML Encoder