├── lib ├── __init__.py └── toolbox.py ├── ptt ├── data │ └── .gitkeep ├── requirements.txt └── crawler.py ├── CNAME ├── bb102 ├── yes123 │ ├── detail_html │ │ └── .gitkeep │ ├── list_html │ │ └── .gitkeep │ ├── job_detail.py │ └── job_list.py ├── cai_speech.txt └── donald_trump.txt ├── _config.yml ├── bb103 ├── pm2.png ├── bb103_pythonetl_20170829.ipynb └── trump_interview.txt ├── utils ├── chromedriver ├── chromedriver_linux64.zip └── install_chromedriver.sh ├── bb105 ├── yes123 │ ├── yes123.py │ ├── requirements.txt │ ├── README.md │ └── tasks.py ├── ptt_crawler.py └── .ipynb_checkpoints │ └── bb105_20171225-checkpoint.ipynb ├── datasets ├── A_LVR_LAND_A_BUILD.CSV ├── eng_stop_words.txt └── trump_speech.txt ├── install_gcin.sh ├── README.md ├── cb101 ├── CB101_20180607.ipynb ├── 時間日期轉換.ipynb └── flippingmed_crawler.ipynb ├── bb106 ├── bb106_20180402.ipynb └── google_trends.py └── bb104 ├── appledaily.py ├── amazon.ipynb └── bb104_20171109.ipynb /lib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ptt/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | pythonetl.ianchenhq.com -------------------------------------------------------------------------------- /bb102/yes123/detail_html/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bb102/yes123/list_html/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /bb103/pm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianchen06/pythonetl/HEAD/bb103/pm2.png -------------------------------------------------------------------------------- /utils/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianchen06/pythonetl/HEAD/utils/chromedriver -------------------------------------------------------------------------------- /bb105/yes123/yes123.py: -------------------------------------------------------------------------------- 1 | import tasks 2 | 3 | [tasks.get_list.delay(page) for page in range(1,11)] 4 | 5 | -------------------------------------------------------------------------------- /datasets/A_LVR_LAND_A_BUILD.CSV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianchen06/pythonetl/HEAD/datasets/A_LVR_LAND_A_BUILD.CSV -------------------------------------------------------------------------------- /ptt/requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2017.11.5 2 | chardet==3.0.4 3 | idna==2.6 4 | requests==2.18.4 5 | urllib3==1.22 6 | -------------------------------------------------------------------------------- /utils/chromedriver_linux64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianchen06/pythonetl/HEAD/utils/chromedriver_linux64.zip -------------------------------------------------------------------------------- /utils/install_chromedriver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Installing Chromedriver..." 3 | wget https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip 4 | unzip chromedriver_linux64.zip 5 | sudo cp chromedriver /usr/local/bin 6 | -------------------------------------------------------------------------------- /bb105/yes123/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==2.2.2 2 | billiard==3.5.0.3 3 | celery==4.1.0 4 | certifi==2018.1.18 5 | chardet==3.0.4 6 | idna==2.6 7 | kombu==4.1.0 8 | pytz==2017.3 9 | requests==2.18.4 10 | rethinkdb==2.3.0.post6 11 | urllib3==1.22 12 | vine==1.1.4 13 | -------------------------------------------------------------------------------- /install_gcin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -ex 3 | 4 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 835AB0E3 5 | 6 | cat <>/etc/apt/sources.list 7 | deb http://hyperrate.com/gcin-ubuntu1604 eliu release 8 | EOF 9 | 10 | sudo apt-get update && sudo apt-get install -y gcin 11 | -------------------------------------------------------------------------------- /bb102/yes123/job_detail.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | import requests as r 4 | 5 | HOST = 'https://www.yes123.com.tw/admin/' 6 | 7 | def get_detail(): 8 | with open('./urls_uniq.txt') as f: 9 | for line in f: 10 | URL = HOST + line.strip() 11 | print("[INFO] crawling %s"%URL) 12 | res = r.get(URL, headers={'User-Agent': ''}) 13 | job_id = line.split("=")[-1].strip() 14 | print(res.status_code) 15 | with open('./detail_html/java_job_%s.html'%job_id, 'w') as f: 16 | f.write(res.text) 17 | -------------------------------------------------------------------------------- /lib/toolbox.py: -------------------------------------------------------------------------------- 1 | """This is a toolbox module for our crawler 2 | 3 | :author: 4 | """ 5 | def gen_header(header_str): 6 | """This function generates a header_dict from Chrome dev tool for requests library 7 | 8 | :param header_str: The header string copied from Chrome developer tool. 9 | :type header_str: str 10 | :returns: header dictionary 11 | """ 12 | header_dict = {} 13 | rows = header_str.split('\n') 14 | for row in rows: 15 | kv_list = row.split(":") # 把每一行用: split()開 16 | 17 | # kv_list = ['key1', 'https', '//ianchenhq.com'] 18 | key = kv_list[0] 19 | val = ':'.join(kv_list[1:]) # 再用:把1到結尾的element重新組合起來 -> https://ianchenhq.com 20 | header_dict[key] = val 21 | return header_dict -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python ETL Jupyter Notebooks 2 | 3 | ## 如何安裝環境 4 | 5 | 以下是如何在Linux/Mac底下安裝Python環境 6 | 7 | 參照 https://github.com/pyenv/pyenv/wiki 8 | 9 | ### Linux 10 | 11 | ``` 12 | # 更新系統套件版本列表 13 | sudo apt-get update 14 | 15 | # 安裝C語言build tools 16 | apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev 17 | ``` 18 | 19 | ### MacOS 20 | 21 | ``` 22 | # 安裝homebrew 23 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 24 | 25 | # 安裝一些系統套件 26 | brew install openssl readline xz 27 | ``` 28 | 29 | ### Linux/MacOS 30 | 31 | ``` 32 | # 安裝pyenv 33 | curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash 34 | ``` -------------------------------------------------------------------------------- /ptt/crawler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import re 3 | import os 4 | 5 | import requests 6 | 7 | HOST = "https://www.ptt.cc" 8 | URL_TPL = "https://www.ptt.cc/bbs/Gossiping/index%s.html" 9 | PG_TO_CRAWL = 5 10 | 11 | resp = requests.get("https://www.ptt.cc/bbs/Gossiping/index.html", headers={'cookie': 'over18=1'}) 12 | 13 | total_page = int(re.findall('/bbs/Gossiping/index(\d+).html', resp.text)[-1]) + 1 14 | 15 | for pg in range(total_page, total_page - PG_TO_CRAWL, -1): 16 | url = URL_TPL%pg 17 | print(url) 18 | resp = requests.get(url, headers={'cookie': 'over18=1'}) 19 | articles = re.findall('/bbs/Gossiping/M.+\.html', resp.text) 20 | for link in [HOST + link for link in articles]: 21 | resp = requests.get(link, headers={'cookie': 'over18=1'}) 22 | with open('./data/%s'%(os.path.basename(link)), 'w') as f: 23 | f.write(resp.text) 24 | 25 | -------------------------------------------------------------------------------- /bb105/yes123/README.md: -------------------------------------------------------------------------------- 1 | # YES123 爬蟲 2 | 3 | ## Dependencies 4 | 5 | 1. Python 3.5+ 6 | 1. pip 7 | 1. Docker 8 | 9 | ## Getting Started 10 | 11 | ```bash 12 | virtualenv venv 13 | source venv/bin/activate 14 | pip install -r requirements.txt 15 | 16 | # Start Rabbitmq 17 | docker run --name some-rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_USERNAME=celery -e RABBITMQ_PASSWORD=celery -d bitnami/rabbitmq:latest 18 | 19 | # Start RethinkDB 20 | docker run --name some-rethink -p 28015:28015 -p 8080:8080 -v "$PWD:/data" -d rethinkdb:2.3.6 21 | 22 | # Start celery worker, c is the concurrency level 23 | celery -A tasks worker -c 4 --loglevel=info 24 | 25 | # In another terminal 26 | source venv/bin/activate 27 | 28 | # Launch job manually 29 | python yes123.py 30 | 31 | ``` 32 | 33 | Add the job dispatcher in crontab for automatic job dispatch 34 | ``` 35 | # crontab 36 | * * * * * python yes123.py 37 | ``` -------------------------------------------------------------------------------- /cb101/CB101_20180607.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Untitled0.ipynb", 7 | "version": "0.3.2", 8 | "views": {}, 9 | "default_view": {}, 10 | "provenance": [], 11 | "collapsed_sections": [] 12 | }, 13 | "kernelspec": { 14 | "name": "python3", 15 | "display_name": "Python 3" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "metadata": { 21 | "id": "WhBDAFmmOHGq", 22 | "colab_type": "code", 23 | "colab": { 24 | "autoexec": { 25 | "startup": false, 26 | "wait_interval": 0 27 | } 28 | } 29 | }, 30 | "cell_type": "code", 31 | "source": [ 32 | "https://github.com/ianchen06/distributed_crawler" 33 | ], 34 | "execution_count": 0, 35 | "outputs": [] 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /bb106/bb106_20180402.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "https://github.com/ianchen06/pythonetl/raw/master/bb106/google_trends.py" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "https://github.com/ianchen06/google_trends_crawler" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "celery\n", 22 | "\n", 23 | "http://www.celeryproject.org" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "rabbitmq\n", 31 | "\n", 32 | "https://www.rabbitmq.com" 33 | ] 34 | } 35 | ], 36 | "metadata": { 37 | "kernelspec": { 38 | "display_name": "Python 3", 39 | "language": "python", 40 | "name": "python3" 41 | }, 42 | "language_info": { 43 | "codemirror_mode": { 44 | "name": "ipython", 45 | "version": 3 46 | }, 47 | "file_extension": ".py", 48 | "mimetype": "text/x-python", 49 | "name": "python", 50 | "nbconvert_exporter": "python", 51 | "pygments_lexer": "ipython3", 52 | "version": "3.6.4" 53 | } 54 | }, 55 | "nbformat": 4, 56 | "nbformat_minor": 2 57 | } 58 | -------------------------------------------------------------------------------- /bb106/google_trends.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import sys 3 | import datetime 4 | 5 | from pymongo import MongoClient 6 | import pymongo 7 | import requests 8 | import json 9 | 10 | start_date = sys.argv[1] 11 | days = int(sys.argv[2]) 12 | 13 | conn = MongoClient() 14 | 15 | for day in range(1,days + 1): 16 | dstr = (datetime.datetime.strptime(start_date,'%Y%m%d') - datetime.timedelta(days=day)).strftime("%Y%m%d") 17 | 18 | print("[DEBUG] Requesting %s"%dstr) 19 | url = "https://trends.google.com/trends/hottrends/hotItems" 20 | data = { 21 | "ajax": "1", 22 | "pn": "p12", 23 | "htd": dstr, 24 | "htv": "l" 25 | } 26 | 27 | headers = { 28 | "accept": "*/*", 29 | "accept-encoding": "gzip, deflate, br", 30 | "accept-language": "en-US,en;q=0.9,zh-TW;q=0.8,zh;q=0.7", 31 | "cache-control": "no-cache", 32 | "content-length": "32", 33 | "content-type": "application/x-www-form-urlencoded;charset=UTF-8", 34 | "origin": "https://trends.google.com", 35 | "pragma": "no-cache", 36 | "referer": "https://trends.google.com/trends/hottrends", 37 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" 38 | } 39 | 40 | resp = requests.post(url, data=data, headers=headers) 41 | data = resp.json() 42 | print("[INFO] %s"%data.get('oldestVisibleDate')) 43 | data['_id'] = data.get('oldestVisibleDate') 44 | 45 | # conn... 46 | try: 47 | res = conn.crawler.google_trends.insert(data) 48 | print("[INFO] Inserted id %s"%res) 49 | except pymongo.errors.DuplicateKeyError as e: 50 | print(e) 51 | print("[INFO] %s exists, skipping"%data['_id']) 52 | -------------------------------------------------------------------------------- /bb104/appledaily.py: -------------------------------------------------------------------------------- 1 | """ 2 | Apple Daily Crawler 3 | 4 | author: Ian Chen 5 | """ 6 | import re 7 | import csv 8 | 9 | import requests 10 | from bs4 import BeautifulSoup 11 | 12 | DOMAIN = "http://www.appledaily.com.tw" 13 | 14 | f = open('./data.csv', 'w') 15 | headers = ['title', 'dt', 'content', 'view_count'] 16 | writer = csv.DictWriter(f, fieldnames=headers) 17 | 18 | writer.writeheader() 19 | 20 | def article_crawler(url): 21 | """ 22 | Crawls article url, and extract fields 23 | 24 | args: 25 | url : article url 26 | 27 | return: 28 | article_dict : artilce dict with fields 29 | """ 30 | resp = requests.get(url) 31 | soup = BeautifulSoup(resp.text, 'html5lib') 32 | 33 | article = {} 34 | article['title'] = soup.select_one('#h1').text.replace('\u3000',' ').strip() 35 | article['dt'] = soup.select_one('div.gggs > time').text.strip() 36 | article['content'] = soup.select_one('#summary').text.strip() 37 | 38 | if soup.select_one('div.urcc > a.function_icon.clicked'): 39 | article['view_count'] = int(re.findall('\d+', soup.select_one('div.urcc > a.function_icon.clicked').text)[0]) 40 | else: 41 | article['view_count'] = 0 42 | writer.writerow(article) 43 | f.flush() # Flush here so we don't loose data on exception 44 | return article 45 | 46 | def list_crawler(pg=5): 47 | """ 48 | Cralers appledaiy's realtime news 49 | 50 | args: 51 | pg : number of pages to crawl 52 | """ 53 | url = DOMAIN + "/realtimenews/section/new/%s" 54 | 55 | article_data = [] 56 | 57 | for p in range(1,pg+1): 58 | print("[INFO] crawling %s"%url%p) 59 | resp = requests.get(url%p) 60 | urls = [DOMAIN + x for x in re.findall('href="(/realtimenews/article/.*/.*/.*/.+)" target', resp.text)] 61 | for article_url in urls: 62 | article_data.append(article_crawler(article_url)) 63 | 64 | if __name__ == "__main__": 65 | list_crawler(1) 66 | 67 | -------------------------------------------------------------------------------- /bb105/ptt_crawler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | import re 4 | 5 | import requests 6 | 7 | DATA_PATH = '/tmp/ptt_data' 8 | CRAWL_PAGE_CNT = 10 9 | URL_TEMPLATE = "https://www.ptt.cc/bbs/Gossiping/index{}.html" 10 | HOST = "https://www.ptt.cc" 11 | 12 | 13 | def get_w_cookie(url): 14 | """GET HTTP url with custom header containing cookie info for PTT 15 | 16 | Parameters 17 | ---------- 18 | url : str 19 | PTT八卦版需要驗證年齡的URL, 20 | 如:https://www.ptt.cc/bbs/Gossiping/index31063.html 21 | 22 | Returns 23 | ------- 24 | Response 25 | Requestsµ模組的Response Object 26 | """ 27 | custom_headers = { 28 | "cookie": "over18=1;" 29 | } 30 | resp = requests.get(url, headers=custom_headers) 31 | return resp 32 | 33 | 34 | def get_total_page_cnt(): 35 | """取得現在ptt板塊的總頁數 36 | 37 | Parameters 38 | ---------- 39 | 40 | Returns 41 | ------- 42 | int 43 | 現在ptt板塊的總頁數 44 | """ 45 | url = URL_TEMPLATE.format('') 46 | resp = get_w_cookie(url) 47 | 48 | # 這個符號 49 | # ‹-> ‹ 50 | total_page_cnt = int(re.findall('href="/bbs/Gossiping/index(\d+).html">‹ 上頁', resp.text)[0]) + 1 51 | return total_page_cnt 52 | 53 | def get_list_page(url): 54 | """GET列表頁,取得內文頁的連結們 55 | 56 | Parameters 57 | ---------- 58 | url : str 59 | PTT 列表頁URL 60 | 61 | Returns 62 | ------- 63 | list 64 | PTT內文頁的links 65 | """ 66 | resp = get_w_cookie(url) 67 | links = re.findall('.+', resp.text) 68 | detail_page_links = [HOST + link for link in links] 69 | return detail_page_links 70 | 71 | def dump_page(url): 72 | """GET url的HTML並且寫到檔案裡 73 | 74 | Parameters 75 | ---------- 76 | url : str 77 | PTT 內文頁URL 78 | 79 | Returns 80 | ------- 81 | str 82 | 儲存的檔案名稱 83 | """ 84 | filename = "_".join(url.split('/')[-1].split('.')[:-1]) + '.html' 85 | resp = get_w_cookie(url) 86 | 87 | with open(DATA_PATH + '/' + filename, 'w') as f: 88 | f.write(resp.text) 89 | return filename 90 | 91 | if __name__ == "__main__": 92 | """ 93 | 以下的code只有被單獨跑的時候才會執行 94 | 被import的時候不會執行 95 | """ 96 | total_page_cnt = get_total_page_cnt() 97 | 98 | for pg in range(total_page_cnt, total_page_cnt - CRAWL_PAGE_CNT, -1): 99 | url = URL_TEMPLATE.format(pg) 100 | for link in get_list_page(url): 101 | print(link) 102 | dump_page(link) 103 | 104 | -------------------------------------------------------------------------------- /datasets/eng_stop_words.txt: -------------------------------------------------------------------------------- 1 | – 2 | !! 3 | ?! 4 | ?? 5 | !? 6 | ` 7 | `` 8 | '' 9 | -lrb- 10 | -rrb- 11 | -lsb- 12 | -rsb- 13 | , 14 | . 15 | : 16 | ; 17 | " 18 | ' 19 | ? 20 | < 21 | > 22 | { 23 | } 24 | [ 25 | ] 26 | + 27 | - 28 | ( 29 | ) 30 | & 31 | % 32 | $ 33 | @ 34 | ! 35 | ^ 36 | # 37 | * 38 | .. 39 | ... 40 | 'll 41 | 's 42 | 'm 43 | a 44 | about 45 | above 46 | after 47 | again 48 | against 49 | all 50 | am 51 | an 52 | and 53 | any 54 | are 55 | aren't 56 | as 57 | at 58 | be 59 | because 60 | been 61 | before 62 | being 63 | below 64 | between 65 | both 66 | but 67 | by 68 | can 69 | can't 70 | cannot 71 | could 72 | couldn't 73 | did 74 | didn't 75 | do 76 | does 77 | doesn't 78 | doing 79 | don't 80 | down 81 | during 82 | each 83 | few 84 | for 85 | from 86 | further 87 | had 88 | hadn't 89 | has 90 | hasn't 91 | have 92 | haven't 93 | having 94 | he 95 | he'd 96 | he'll 97 | he's 98 | her 99 | here 100 | here's 101 | hers 102 | herself 103 | him 104 | himself 105 | his 106 | how 107 | how's 108 | i 109 | i'd 110 | i'll 111 | i'm 112 | i've 113 | if 114 | in 115 | into 116 | is 117 | isn't 118 | it 119 | it's 120 | its 121 | itself 122 | let's 123 | me 124 | more 125 | most 126 | mustn't 127 | my 128 | myself 129 | no 130 | nor 131 | not 132 | of 133 | off 134 | on 135 | once 136 | only 137 | or 138 | other 139 | ought 140 | our 141 | ours 142 | ourselves 143 | out 144 | over 145 | own 146 | same 147 | shan't 148 | she 149 | she'd 150 | she'll 151 | she's 152 | should 153 | shouldn't 154 | so 155 | some 156 | such 157 | than 158 | that 159 | that's 160 | the 161 | their 162 | theirs 163 | them 164 | themselves 165 | then 166 | there 167 | there's 168 | these 169 | they 170 | they'd 171 | they'll 172 | they're 173 | they've 174 | this 175 | those 176 | through 177 | to 178 | too 179 | under 180 | until 181 | up 182 | very 183 | was 184 | wasn't 185 | we 186 | we'd 187 | we'll 188 | we're 189 | we've 190 | were 191 | weren't 192 | what 193 | what's 194 | when 195 | when's 196 | where 197 | where's 198 | which 199 | while 200 | who 201 | who's 202 | whom 203 | why 204 | why's 205 | with 206 | won't 207 | would 208 | wouldn't 209 | you 210 | you'd 211 | you'll 212 | you're 213 | you've 214 | your 215 | yours 216 | yourself 217 | yourselves 218 | ### 219 | return 220 | arent 221 | cant 222 | couldnt 223 | didnt 224 | doesnt 225 | dont 226 | hadnt 227 | hasnt 228 | havent 229 | hes 230 | heres 231 | hows 232 | im 233 | isnt 234 | its 235 | lets 236 | mustnt 237 | shant 238 | shes 239 | shouldnt 240 | thats 241 | theres 242 | theyll 243 | theyre 244 | theyve 245 | wasnt 246 | were 247 | werent 248 | whats 249 | whens 250 | wheres 251 | whos 252 | whys 253 | wont 254 | wouldnt 255 | youd 256 | youll 257 | youre 258 | youve 259 | -------------------------------------------------------------------------------- /bb102/cai_speech.txt: -------------------------------------------------------------------------------- 1 | 各位友邦的元首與貴賓、各國駐台使節及代表、現場的好朋友,全體國人同胞,大家好 2 | 3 | 感謝與承擔 4 | 5 | 就在剛剛,我和陳建仁已經在總統府裡面,正式宣誓就任中華民國第十四任總統與副總統。我們要感謝這塊土地對我們的栽培,感謝人民對我們的信任,以及,最重要的,感謝這個國家的民主機制,讓我們透過和平的選舉過程,實現第三次政黨輪替,並且克服種種不確定因素,順利渡過長達四個月的交接期,完成政權和平移轉。 6 | 7 | 台灣,再一次用行動告訴世界,作為一群民主人與自由人,我們有堅定的信念,去捍衛民主自由的生活方式。這段旅程,我們每一個人都參與其中。親愛的台灣人民,我們做到了。 8 | 9 | 我要告訴大家,對於一月十六日的選舉結果,我從來沒有其他的解讀方式。人民選擇了新總統、新政府,所期待的就是四個字:解決問題。此時此刻,台灣的處境很困難,迫切需要執政者義無反顧的承擔。這一點,我不會忘記。 10 | 11 | 我也要告訴大家,眼前的種種難關,需要我們誠實面對,需要我們共同承擔。所以,這個演說是一個邀請,我要邀請全體國人同胞一起來,扛起這個國家的未來。 12 | 13 | 國家不會因為領導人而偉大;全體國民的共同奮鬥,才讓這個國家偉大。總統該團結的不只是支持者,總統該團結的是整個國家。團結是為了改變,這是我對這個國家最深切的期待。在這裡,我要誠懇地呼籲,請給這個國家一個機會,讓我們拋下成見,拋下過去的對立,我們一起來完成新時代交給我們的使命。 14 | 15 | 在我們共同奮鬥的過程中,身為總統,我要向全國人民宣示,未來我和新政府,將領導這個國家的改革,展現決心,絕不退縮。 16 | 17 | 為年輕人打造一個更好的國家 18 | 19 | 未來的路並不好走,台灣需要一個正面迎向一切挑戰的新政府,我的責任就是領導這個新政府。 20 | 21 | 我們的年金制度,如果不改,就會破產。 22 | 我們僵化的教育制度,已經逐漸與社會脈動脫節。 23 | 我們的能源與資源十分有限,我們的經濟缺乏動能,舊的代工模式已經面臨瓶頸,整個國家極需要新的經濟發展模式。 24 | 我們的人口結構急速老化,長照體系卻尚未健全。 25 | 我們的人口出生率持續低落,完善的托育制度卻始終遙遙無期。 26 | 我們環境汙染問題仍然嚴重。 27 | 我們國家的財政並不樂觀。 28 | 我們的司法已經失去人民的信任。 29 | 我們的食品安全問題,困擾著所有家庭。 30 | 我們的貧富差距越來越嚴重。 31 | 我們的社會安全網還是有很多破洞。 32 | 最重要的,我要特別強調,我們的年輕人處於低薪的處境,他們的人生,動彈不得,對於未來,充滿無奈與茫然。 33 | 34 | 年輕人的未來是政府的責任。如果不友善的結構沒有改變,再多個人菁英的出現,都不足以讓整體年輕人的處境變好。我期許自己,在未來的任期之內,要一步一步,從根本的結構來解決這個國家的問題。 35 | 36 | 這就是我想為台灣的年輕人做的事。雖然我沒有辦法立刻幫所有的年輕人加薪,但是我願意承諾,新政府會立刻展開行動。請給我們一點時間,也請跟我們一起走上改革的這一條路。 37 | 38 | 改變年輕人的處境,就是改變國家的處境。一個國家的年輕人沒有未來,這個國家必定沒有未來。幫助年輕人突破困境,實現世代正義,把一個更好的國家交到下一代手上,就是新政府重大的責任。 39 | 40 | 第一、經濟結構的轉型 41 | 42 | 要打造一個更好的國家,未來,新政府要做到以下幾件事情。 43 | 44 | 首先,就是讓台灣的經濟結構轉型。這是新政府所必須承擔的最艱鉅使命。我們不要妄自菲薄,更不要失去信心。台灣有很多別的國家沒有的優勢,我們有海洋經濟的活力和靭性,高素質的人力資源、務實可靠的工程師文化、完整的產業鏈、敏捷靈活的中小企業,以及,永不屈服的創業精神。 45 | 46 | 我們要讓台灣經濟脫胎換骨,就必須從現在起就下定決心,勇敢地走出另外一條路。這一條路,就是打造台灣經濟發展的新模式。 47 | 48 | 新政府將打造一個以創新、就業、分配為核心價值,追求永續發展的新經濟模式。改革的第一步,就是強化經濟的活力與自主性,加強和全球及區域的連結,積極參與多邊及雙邊經濟合作及自由貿易談判,包括TPP、RCEP等,並且,推動新南向政策,提升對外經濟的格局及多元性,告別以往過於依賴單一市場的現象。 49 | 50 | 除此之外,新政府相信,唯有激發新的成長動能,我們才能突破當前經濟的停滯不前。我們會以出口和內需作為雙引擎,讓企業生產和人民生活互為表裡,讓對外貿易和在地經濟緊密連結。 51 | 52 | 我們會優先推動五大創新研發計畫,藉著這些產業來重新塑造台灣的全球競爭力。我們也要積極提升勞動生產力,保障勞工權益,讓薪資和經濟成長能同步提升。 53 | 54 | 這是台灣經濟發展的關鍵時刻。我們有決心,也有溝通能力。我們已經有系統性的規劃,未來,會以跨部會聯手的模式,把整個國家的力量集結起來,一起來催生這個新模式。 55 | 56 | 在經濟發展的同時,我們不要忘記對環境的責任。經濟發展的新模式會和國土規劃、區域發展及環境永續,相互結合。產業的佈局和國土的利用,應該拋棄零碎的規畫,和短視近利的眼光。我們必須追求區域的均衡發展,這需要中央來規畫、整合,也需要地方政府充分發揮區域聯合治理的精神。 57 | 58 | 我們也不能再像過去,無止盡地揮霍自然資源及國民健康。所以,對各種汙染的控制,我們會嚴格把關,更要讓台灣走向循環經濟的時代,把廢棄物轉換為再生資源。對於能源的選擇,我們會以永續的觀念去逐步調整。新政府會嚴肅看待氣候變遷、國土保育、災害防治的相關議題,因為,我們只有一個地球,我們也只有一個台灣。 59 | 60 | 第二、強化社會安全網 61 | 62 | 新政府必須要承擔的第二件事情,就是強化台灣的社會安全網。這些年,幾件關於兒少安全及隨機殺人的事件,都讓整個社會震驚。不過,一個政府不能永遠在震驚,它必須要有同理心。沒有人可以替受害者家屬承受傷痛,但是,一個政府,尤其是第一線處理問題的人,必須要讓受害者以及家屬覺得,不幸事件發生的時候,政府是站在他們這一邊。 63 | 64 | 除了同理心之外,政府更應該要提出解決的方法。全力防止悲劇一再發生,從治安、教育、心理健康、社會工作等各個面向,積極把破洞補起來。尤其是治安與反毒的工作,這些事情,新政府會用最嚴肅的態度和行動來面對。 65 | 66 | 在年金的改革方面,這是攸關台灣生存發展的關鍵改革,我們不應該遲疑,也不可以躁進。由陳建仁副總統擔任召集人的年金改革委員會,已經緊鑼密鼓在籌備之中。過去的政府在這個議題上,曾經有過一些努力。但是,缺乏社會的參與。新政府的做法,是發動一個集體協商,因為年金改革必須是一個透過協商來團結所有人的過程。 67 | 68 | 這就是為什麼,我們要召開年金改革國是會議,由不同階層、不同職業代表,在社會團結的基礎上,共同協商。一年之內,我們會提出可行的改革方案。無論是勞工還是公務員,每一個國民的退休生活都應該得到公平的保障。 69 | 70 | 另外,在長期照顧的議題上,我們將會把優質、平價、普及的長期照顧系統建立起來。和年金改革一樣,長照體系也是一個社會總動員的過程。新政府的做法是由政府主導和規劃,鼓勵民間發揮社區主義的精神,透過社會集體互助的力量,來建立一套妥善而完整的體系。每一個老年人都可以在自己熟悉的社區,安心享受老年生活,每一個家庭的照顧壓力將會減輕。照顧老人的工作不能完全讓它變成自由市場。我們會把責任扛起來,按部就班來規劃與執行,為超高齡社會的來臨,做好準備。 71 | 72 | 第三、社會的公平與正義 73 | 74 | 新政府要承擔的第三件事情,就是社會的公平與正義。在這個議題上,新政府會持續和公民社會一起合作,讓台灣的政策更符合多元、平等、開放、透明、人權的價值,讓台灣的民主機制更加深化與進化。 75 | 76 | 新的民主制度要能夠上路,我們必須先找出面對過去的共同方法。未來,我會在總統府成立真相與和解委員會,用最誠懇與謹慎的態度,來處理過去的歷史。追求轉型正義的目標是在追求社會的真正和解,讓所有台灣人都記取那個時代的錯誤。 77 | 78 | 我們將從真相的調查與整理出發,預計在三年之內,完成台灣自己的轉型正義調查報告書。我們將會依據調查報告所揭示的真相,來進行後續的轉型正義工作。挖掘真相、彌平傷痕、釐清責任。從此以後,過去的歷史不再是台灣分裂的原因,而是台灣一起往前走的動力。 79 | 80 | 同樣在公平正義的議題上,我會秉持相同的原則,來面對原住民族的議題。今天的就職典禮,原住民族的小朋友在唱國歌之前,先唱了他們部落傳統的古調。這象徵了,我們不敢忘記,這個島上先來後到的順序。 81 | 82 | 新政府會用道歉的態度,來面對原住民族相關議題,重建原民史觀,逐步推動自治,復育語言文化,提升生活照顧,這就是我要領導新政府推動的改變。 83 | 84 | 接下來,新政府也會積極推動司法改革。這是現階段台灣人民最關心的議題。司法無法親近人民、不被人民信任、司法無法有效打擊犯罪,以及,司法失去作為正義最後一道防線的功能,是人民普遍的感受。 85 | 86 | 為了展現新政府的決心,我們會在今年十月召開司法國是會議,透過人民實際的參與,讓社會力進來,一起推動司法改革。司法必須回應人民的需求,不再只是法律人的司法,而是全民的司法。司法改革也不只是司法人的家務事,而是全民參與的改革。這就是我對司法改革的期待。 87 | 88 | 第四、區域的和平穩定發展及兩岸關係 89 | 90 | 新政府要承擔的第四件事情,是區域的和平穩定與發展,以及妥善處理兩岸關係。過去三十年,無論是對亞洲或是全球,都是變動最劇烈的時期;而全球及區域的經濟穩定和集體安全,也是各國政府越來越關切的課題。 91 | 92 | 台灣在區域發展當中,一直是不可或缺的關鍵角色。但是近年來,區域的情勢快速變動,如果台灣不善用自己的實力和籌碼,積極參與區域事務,不但將會變得無足輕重,甚至可能被邊緣化,喪失對於未來的自主權。 93 | 94 | 我們有危機,但也有轉機。台灣現階段的經濟發展,和區域中許多國家高度關聯和互補。如果將打造經濟發展新模式的努力,透過和亞洲、乃至亞太區域的國家合作,共同形塑未來的發展策略,不但可以為區域的經濟創新、結構調整和永續發展,做出積極的貢獻,更可以和區域內的成員,建立緊密的「經濟共同體」意識。 95 | 96 | 我們要和其他國家共享資源、人才與市場,擴大經濟規模,讓資源有效利用。「新南向政策」就是基於這樣的精神。我們會在科技、文化與經貿等各層面,和區域成員廣泛交流合作,尤其是增進與東協、印度的多元關係。為此,我們也願意和對岸,就共同參與區域發展的相關議題,坦誠交換意見,尋求各種合作與協力的可能性。 97 | 98 | 在積極發展經濟的同時,亞太地區的安全情勢也變得越來越複雜,而兩岸關係,也成為建構區域和平與集體安全的重要一環。這個建構的進程,台灣會做一個「和平的堅定維護者」,積極參與,絕不缺席;我們也將致力維持兩岸關係的和平穩定;我們更會努力促成內部和解,強化民主機制,凝聚共識,形成一致對外的立場。 99 | 100 | 對話和溝通,是我們達成目標最重要的關鍵。台灣也要成為一個「和平的積極溝通者」,我們將和相關的各方,建立常態、緊密的溝通機制,隨時交換意見,防止誤判,建立互信,有效解決爭議。我們將謹守和平原則、利益共享原則,來處理相關的爭議。 101 | 102 | 我依照中華民國憲法當選總統,我有責任捍衛中華民國的主權和領土;對於東海及南海問題,我們主張應擱置爭議,共同開發。 103 | 104 | 兩岸之間的對話與溝通,我們也將努力維持現有的機制。1992年兩岸兩會秉持相互諒解、求同存異的政治思維,進行溝通協商,達成若干的共同認知與諒解,我尊重這個歷史事實。92年之後,20多年來雙方交流、協商所累積形成的現狀與成果,兩岸都應該共同珍惜與維護,並在這個既有的事實與政治基礎上,持續推動兩岸關係和平穩定發展;新政府會依據中華民國憲法、兩岸人民關係條例及其他相關法律,處理兩岸事務。兩岸的兩個執政黨應該要放下歷史包袱,展開良性對話,造福兩岸人民。 105 | 106 | 我所講的既有政治基礎,包含幾個關鍵元素,第一,1992年兩岸兩會會談的歷史事實與求同存異的共同認知,這是歷史事實;第二,中華民國現行憲政體制;第三,兩岸過去20多年來協商和交流互動的成果;第四,台灣民主原則及普遍民意。 107 | 108 | 第五、外交與全球性議題 109 | 110 | 新政府要承擔的第五件事情,是善盡地球公民的責任,在外交與全球性的議題上做出貢獻。讓台灣走向世界,也要讓世界走進台灣。 111 | 112 | 現場有許多來自各國的元首與使節團,我要特別謝謝他們,長久以來一直幫助台灣,讓我們有機會參與國際社會。未來,我們會持續透過官方互動、企業投資與民間合作各種方式,分享台灣發展的經驗,與友邦建立永續的夥伴關係。 113 | 114 | 台灣是全球公民社會的模範生,民主化以來,我們始終堅持和平、自由、民主及人權的普世價值。我們會秉持這個精神,加入全球議題的價值同盟。我們會繼續深化與包括美國、日本、歐洲在內的友好民主國家的關係,在共同的價值基礎上,推動全方位的合作。 115 | 116 | 我們會積極參與國際經貿合作及規則制定,堅定維護全球的經濟秩序,並且融入重要的區域經貿體系。我們也不會在防制全球暖化、氣候變遷的議題上缺席。我們將會在行政院設立專責的能源和減碳辦公室,並且根據COP21巴黎協議的規定,定期檢討溫室氣體的減量目標,與友好國家攜手,共同維護永續的地球。 117 | 118 | 同時,新政府會支持並參與,全球性新興議題的國際合作,包括人道救援、醫療援助、疾病的防治與研究、反恐合作,以及共同打擊跨國犯罪,讓台灣成為國際社會不可或缺的夥伴。 119 | 120 | 結語 121 | 122 | 1996年台灣第一次總統直選,到今天剛好20年。過去20年,在幾任政府以及公民社會的努力之下,我們成功渡過了許多新興民主國家必須面對的難關。在這個過程中,我們曾經有過許多感動人心的時刻和故事,不過,正如同世界上其他國家一樣,我們也曾經有過焦慮、不安、矛盾、與對立。 123 | 124 | 我們看到了社會的對立,進步與保守的對立,環境與開發的對立,以及,政治意識之間的對立。這些對立,曾經激發出選舉時的動員能量,不過也因為這些對立,我們的民主逐漸失去了解決問題的能力。 125 | 126 | 民主是一個進程,每一個時代的政治工作者,都要清楚認識他身上所肩負的責任。民主會前進,民主也有可能倒退。今天,我站在這裡,就是要告訴大家,倒退不會是我們的選項。新政府的責任就是把台灣的民主推向下一個階段:以前的民主是選舉的輸贏,現在的民主則是關於人民的幸福;以前的民主是兩個價值觀的對決,現在的民主則是不同價值觀的對話。 127 | 128 | 打造一個沒有被意識形態綁架的「團結的民主」,打造一個可以回應社會與經濟問題的「有效率的民主」,打造一個能夠實質照料人民的「務實的民主」,這就是新時代的意義。 129 | 130 | 只要我們相信,新時代就會來臨。只要這個國家的主人,有堅定的信念,新時代一定會在我們這一代人的手上誕生。 131 | 132 | 各位親愛的台灣人民,演講要結束了,改革要開始了。從這一刻起,這個國家的擔子交在新政府身上。我會讓大家看見這個國家的改變。 133 | 134 | 歷史會記得我們這個勇敢的世代,這個國家的繁榮、尊嚴、團結、自信和公義,都有我們努力的痕跡。歷史會記得我們的勇敢,我們在2016年一起把國家帶向新的方向。這塊土地上的每一個人,都因為參與台灣的改變,而感到驕傲。 135 | 136 | 剛才表演節目中的一首歌曲當中,有一句讓我很感動的歌詞: 137 | (台語)現在是彼一天,勇敢ㄟ台灣人。 138 | 139 | 各位國人同胞,兩千三百萬的台灣人民,等待已經結束,現在就是那一天。今天,明天,未來的每一天,我們都要做一個守護民主、守護自由、守護這個國家的台灣人。 140 | 141 | 謝謝大家。 142 | -------------------------------------------------------------------------------- /bb104/amazon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 27, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "data": { 10 | "text/plain": [ 11 | "'\\n\\n\\n