Web Scraping
泰勞因為好奇,寫了一個 Python 腳本分析這次公投的結果,其實也稱不上是分析,只是很簡單的把同意票與不同意票的資訊抓下來,計算百分比而已。泰勞本身支持以民法保障同性婚姻,因此公投第14案是泰勞最關心的議題,本文會以中選會網頁之公投第14案投票結果作為 Web Scraping 的主要範例喔!
聲明:本文章沒有要討論公投議題的內容。
參考資料:
[The Hitchhiker's Guide to Python]HTML Scraping
在開始之前,先安裝 lxml 和 request
再來這步驟比較麻煩,先用網頁的 Inspector 找出你要的資訊所屬的 Elements。
找出對應的 Elements 之後,再用 html 模組和 xpath 函式來解析資料。
印出來看看結果是否正確吧!area list 儲存的要是縣市區名稱,vote list 儲存的要是同意票數、不同意票數、有效票數和無效票數。
現在可以取得重點資料了,接下來就自由發揮囉!泰勞擬定的目標是找出同意票大於不同意票的地方,從網頁來看,可以細分為縣市、區和投開票所,最小單位是投開票所,所以我們就來找出台北市裡同意公投第14案比例最高的投開票所吧!(泰勞懶惰所以直接無視無效票與投票權人數,只計算同意票與不同意票兩個資料)
跑出來的結果顯示如下圖,原本以為會掛零呢!沒想到其實數量還不少,同意比例最高的地方出現在松山區的第 574 號投開票所,幾乎是 2 比 1。
Web Scraping 不難,但要用在有意義的地方才會突顯它的有趣。泰勞目前掃過了六都的資料,很意外的發現有幾個投開票所同意公投第14案的比例讓人難以置信呢!(灑花~)
GitHubGist:
https://gist.github.com/Kuanlin-Chen/d27089b611cce8fc363f1758acbcb557
聲明:本文章沒有要討論公投議題的內容。
參考資料:
[The Hitchhiker's Guide to Python]HTML Scraping
在開始之前,先安裝 lxml 和 request
s 模組。
$ pip instal lxml requests
透過 requests.get 向網頁請求資料,並且確認伺服器回傳的狀態是否正常。
from lxml import html
import requests
page = requests.get('http://referendum.2018.nat.gov.tw/pc/zh_TW/08/m64000000100000000.html')
if page.status_code == requests.codes.ok:
print 'OK!'
再來這步驟比較麻煩,先用網頁的 Inspector 找出你要的資訊所屬的 Elements。
找出對應的 Elements 之後,再用 html 模組和 xpath 函式來解析資料。
# Parse page by using html module
tree = html.fromstring(page.content)
# Create area list by using xpath function
area = tree.xpath('//td[@valign="bottom"]//text()')
# Create vote list by using xpath function
vote = tree.xpath('//tr[@class="trT"]/td/text()')
tree = html.fromstring(page.content)
# Create area list by using xpath function
area = tree.xpath('//td[@valign="bottom"]//text()')
# Create vote list by using xpath function
vote = tree.xpath('//tr[@class="trT"]/td/text()')
印出來看看結果是否正確吧!area list 儲存的要是縣市區名稱,vote list 儲存的要是同意票數、不同意票數、有效票數和無效票數。
print 'Area : ', area[0]
print 'Agree : ', vote[0]
print 'Disagree : ', vote[1]
print 'Valid : ', vote[2]
print 'Invalid : ', vote[3]
print 'Agree : ', vote[0]
print 'Disagree : ', vote[1]
print 'Valid : ', vote[2]
print 'Invalid : ', vote[3]
現在可以取得重點資料了,接下來就自由發揮囉!泰勞擬定的目標是找出同意票大於不同意票的地方,從網頁來看,可以細分為縣市、區和投開票所,最小單位是投開票所,所以我們就來找出台北市裡同意公投第14案比例最高的投開票所吧!(泰勞懶惰所以直接無視無效票與投票權人數,只計算同意票與不同意票兩個資料)
from lxml import html
import requests
taipei_district_dic = {1:[527,644], 2:[644,786], 3:[1214,1402], 4:[786,919], 5:[1001,1097], 6:[919,1001],7:[1097,1214], 8:[1402,1564], 9:[455,527], 10:[305,455], 11:[142,305], 12:[1,142]}
print '===== Vote for Same-Sex Marriage ====='
for num in range(1,13):
url_head = 'http://referendum.2018.nat.gov.tw/pc/zh_TW/08/m6300000'
url_center = '0000'
url_end = '.html'
for n in range(taipei_district_dic[num][0],taipei_district_dic[num][1]):
page = requests.get(url_head+str("%02d"%num)+url_center+str("%04d"%n)+url_end)
if page.status_code == requests.codes.ok:
tree = html.fromstring(page.content)
area = tree.xpath('//td[@valign="bottom"]//text()')
vote = tree.xpath('//tr[@class="trT"]/td/text()')
# Ex: convert 1,561 into 1561
agree = int(vote[0].replace(',',''))
disagree = int(vote[1].replace(',',''))
if agree > disagree:
percentage = '{:.0%}'.format(float(agree)/float((agree+disagree)))
print area[0] + ' NO.' + str(n) + ' Argee:' + str(agree) + ' Disagree:' + str(disagree) + ' ' + percentage
import requests
taipei_district_dic = {1:[527,644], 2:[644,786], 3:[1214,1402], 4:[786,919], 5:[1001,1097], 6:[919,1001],7:[1097,1214], 8:[1402,1564], 9:[455,527], 10:[305,455], 11:[142,305], 12:[1,142]}
print '===== Vote for Same-Sex Marriage ====='
for num in range(1,13):
url_head = 'http://referendum.2018.nat.gov.tw/pc/zh_TW/08/m6300000'
url_center = '0000'
url_end = '.html'
for n in range(taipei_district_dic[num][0],taipei_district_dic[num][1]):
page = requests.get(url_head+str("%02d"%num)+url_center+str("%04d"%n)+url_end)
if page.status_code == requests.codes.ok:
tree = html.fromstring(page.content)
area = tree.xpath('//td[@valign="bottom"]//text()')
vote = tree.xpath('//tr[@class="trT"]/td/text()')
# Ex: convert 1,561 into 1561
agree = int(vote[0].replace(',',''))
disagree = int(vote[1].replace(',',''))
if agree > disagree:
percentage = '{:.0%}'.format(float(agree)/float((agree+disagree)))
print area[0] + ' NO.' + str(n) + ' Argee:' + str(agree) + ' Disagree:' + str(disagree) + ' ' + percentage
跑出來的結果顯示如下圖,原本以為會掛零呢!沒想到其實數量還不少,同意比例最高的地方出現在松山區的第 574 號投開票所,幾乎是 2 比 1。
Web Scraping 不難,但要用在有意義的地方才會突顯它的有趣。泰勞目前掃過了六都的資料,很意外的發現有幾個投開票所同意公投第14案的比例讓人難以置信呢!(灑花~)
GitHubGist:
https://gist.github.com/Kuanlin-Chen/d27089b611cce8fc363f1758acbcb557
留言
張貼留言