用 requests 網路爬蟲並儲存

今天我們來試試看基本的網站爬蟲吧~~先講一下爬蟲的基本原理:大家看到的所有網頁都是由一份叫做 ” html ” 的文件所構成。講到這邊大家可能會覺得很奇怪:沒道理阿~我們看到的明明就是很多圖案、相片或是按鍵構成的阿 ? 怎麼可能是一份”文件”呢 ? 其實沒錯,所有的網頁背後有一份一份的文件,我們看到的畫面是由瀏覽器 ” 詮釋 ” 出來的結果,所以爬蟲其實背後的運作就是越過瀏覽器直接跟 server 要一份份的 ” 文件 ” ,那利用 Python 蒐集文件有什麼好處呢 ? 第一個就是快,利用 Python 來做,程式一旦開始執行,可以在短時間內做出數十甚至數百下的點擊;第二,我們可以很精準的擷取我們要的資訊,像是在前面利用正規表示式,我們可以把網頁中的信箱都爬取下來;第三,我們可以存檔方便未來查詢,甚至進行數據分析。所以下面我們來看看要怎麼做吧 !!

我們今天就來爬 ” 正規表示式 Regular Expression “(網址:https://wp.me/p9Q764-71) 這篇的網頁,並看看他出來會得到什麼樣子的結果吧 !!

import requests
url = "https://wp.me/p9Q764-71"
page = requests.get(url)
page.encoding = "utf-8"
print(page.text)

上面我可以看到 Python 抓出了一大段的很可怕的內容,但是這些就包含了一整個頁面,當然文章的內容也被包含在這份html當中囉~~未來我們可以利用其他的套件,來擷取出這些內容,甚至是對於內容進行分析。

接下來我們要試著它儲存起來,這樣就可以把這份文件放到我們自己的電腦當中囉~在開始之前需要創建一個資料夾,接著我們把這個料夾的路徑放到程式碼中(我這邊是在C槽中創建一個 ” page ” 資料夾)

建立資料夾完後,我們就開始使用Python來存檔:

file = open(r'c:\\page\page.txt', 'w', encoding = 'UTF-8')
file.write(page.text)
file.close()

這邊事先在page這個資料夾中開一個叫做 page.txt 的檔案,然而此時我們還未建立這份文件,所以電腦會幫你開啟一份 page.txt 的空白文件。接著利用write把內容寫到這份文件,最後還要記得把這份文件關掉才算是大功告成喔~

最後就會在page的資料夾中看到我們剛剛產生的文件,而整個網頁的內容也都被儲存起來囉~

今天的爬蟲只是很初步很初步的開始,Python存在其他的套件來解析這份文件,或著是可以用正規表示式來挖裡面的東西,總而言之,資料在手,希望無窮,大家可以試試看自己去抓取不同的網頁。

利用date_range紀錄日期格式的資料

在處理資料上,常常會遇到需要使用日期格式來記錄的資料,像是捷運公司如果想要紀錄每天乘客的數量,需要這筆資料記錄到某天的日期當中;投資客想要紀錄跟分析台股每天的漲跌狀況;老師需要記錄學生的所以成績;氣象局想要分析每天的溫度或雨量等等的資料。利用date_range便可以輕易地達成目的。對上日期後,我們才能隨心所欲的取出我們要的日期資料,像是比較每年 7/18 號的載客數量、每年一月分到三月份的乘客量與天氣溫度之間的關係等分析,由於依照日期記錄的資料實在是太多太多了,所以這篇會教大家如何創建利用某段日期的 index。

import pandas as pd
pd.date_range('2018-8-01',periods = 31)

首先,他是在 pandas 中的一個模組,所以我們必須要先做import pandas as pd,接著我們就可以使用pd.data_range了,至於我們要如何指定日期區間呢?首先,指定某一天日期,接著在periods參數中指定連續的天數。噹啷~~ 我們便把需要的日期給產生出來啦~~

剛剛有提到參數,相信有些人對於參數還不是那麼的熟悉,什麼是參數呢 ? 之前有說過Python 很大的程度上,是使用人家寫好的現成模組,但是~但是~但是~~人家寫好的code,不一定會完全符合你的需求啊!?所以一般來說,寫好的模組都會提供某些參數設定,讓使用者可以自行調整,像以上面的例子來說,大家創建的index天數一定不相同,所以大家可以藉由自行調整periods來改變天數,除了這個參數以外其實還有很多的參數可以提供大家做更細部的修正,下面我來說明幾個比較常用的參數吧:

  • start:這個參數可以指定開始的日期
  • end:這個參數可以指定結束的日期
  • periods:指定出現次數
  • freq:可以指定間隔的時間(可以使用D(天), H(小時), T(分鐘), S(秒))
  • normalize:可以設定他normalize = True或是normalize = False 。如果利用start 跟end指定的話,開始與結束都會落在最近午夜十二點前。

相信看完這個,很多人還是不知道在幹嘛,沒關係,我們來出幾個題目試試看有沒有辦法自己寫出來吧~~

如果想要指定 2017-01-25 開始到 2017-01-28 ,每隔100分鐘產生一次的話可以怎麼用呢?

import pandas as pd
pd.date_range(start = '2017-01-26', end = '2017-01-28' , freq = '100T')

其中freq = '100T'代表間隔100分鐘。

指定 2017-01-15 開始到 2017-01-16,每隔6小時產生一次的話可以怎麼用呢?

import pandas as pd
pd.date_range(start = '2017-01-15', end = '2019-01-16' , freq = '6H', normalize = True)

最後一個,從2018-05-12每107分鐘產生一次,產生1024筆~~

import pandas as pd
pd.date_range('2018-01-15', freq = '107T', periods = 1024)

這種複雜的情況只要稍微調整一下就可以輕鬆產生出來啦~~大家可以試著看看怎麼修改參數會產生不一樣的資料,另外參數的設定這件事情在Python中非常非常重要,如果可以學會的話,未來可以減少很多的時間。最後一件事情啊~~

要如何看 module 中有那些參數呢?

pd.date_range??

可以打出你想看的模組後,加上兩個?,他就會把說明的文件叫出來拉~~裡面包含模組的說明,可以調整的參數跟參數說明,有的甚至包含範例,大家可以多利用這個功能來看看要如何客製化達到自己想要的功能。

 

快檢視與統計手上的 DataFrame

接下來要來教大家怎麼看自己手邊的資料啦,在 Pandas 裡面有很多內建的指令,可以讓你初步的了解你手邊的資料到底長什麼樣子。(不過這邊因為這邊的資料量很小,所以看起來好像脫褲子放屁,但是未來資料量一大的時候,這些技巧就會變得相當有用。)

這邊首先要請大家先建立一個 DataFrame 的表格,先打入以下程式碼:

import pandas as pd
name = ['Bob', 'Tom', 'Jason', 'Marry', 'Julia', 'John', 'Cathy', 'Andy']
subject = ['Chinese', 'Math', 'Science', 'Music', 'PE', 'History']
scores = [[ 52,85,96,100,75,54],[40,98,93,54,33,20],[100,97,54,55,100,88],
 [72,67,64,53,87,83],[45,90,100,55,34,96], [99,47,85,56,60,100],
 [100,36,89,64,85,50],[85,36,45,79,84,39]]
df = pd.DataFrame(scores, index = name, columns = subject)
df

不知道我在幹嘛嗎?可以來這邊回想一下 DataFrame 到底是什麼~接著就要開始新的教學囉~~把資料讀進來之後,我們來看要怎麼看那些資料吧!!

1.查看首尾資料:

df.head()
df.head(3)
df.tail(4)

使用df.head()可以檢視前五筆資料,聰明大家一定可以類推:df.tail()可以看到後五筆資料。在括號裡面填入數字的話,則更改成想看到的任意組數。輸出的結果在下面,當我們讀入的資料量很龐大的時候,可以利用這種方式來看表格的形式,另外,一份表格在頭尾的地方格式最容易跑掉,所每份資料讀進來的時候可以先用這兩種方式確認資料要如何調整。

2.將index排序:

df.sort_index(axis=1, ascending=True)

在資料表中,我們可以把行跟列的索引值按照順序排列,其中axis = 0的時候,是排”行的索引值axis = 0則是排列的索引值。ascending則是用來選擇要順序或是反序排列。

上面這個是依照行的索引值,把名字字首按照順序排好(A-Z)。

而這個則是將列的索引值按照順序排好。

3.按照數值大小排序:

好接下來假設我們想按照成績的順序來看的話,我們可以利用df.sort_values搭配一個index 來排序。假設我想看按照數學分數的高低將名字做排序,例如下面這樣:

df.sort_values(by='Math')

就會變成下面那樣

4.檢視基礎統計資料:

最後,若是我們想看基礎的統計分析的話,這裡也提供一個簡單快速的指令:df.describe(),我們會發現 Python 將基礎的統計資料都幫我們算出來拉~~

df.describe()

其中 count 代表的是有值出現的次數(有可能會發生數值缺失的狀況,像是這個例子中或許代表他生病沒考到試之類的);mean 就是平均值;std 是標準差;min 最小值;25%是第一四分位數;50%中位數;75%第三四分位數;max 最大值。

好啦~到這堂課應該已經涵蓋”正常人”約80%需要用到的統計數據囉!!不過 TinyCorner 不會到這邊就停止腳步的,因為我們的目標就是要超越普通人,不然這樣其實回去用 Excel就好….(不過如果熟悉的話,絕對還是會比 Excel 快很多)。未來會慢慢用一些其他的統計工具,我也會去找一些真實數據來使用,請大家慢慢期待阿~~

 

series & 建立 DataFrame 表格

今天要來教大家使用Python裡面一個很好用的套件:Pandas(忘記他的可以點這邊)。回想一下,還記得前陣子教的tuplelistdictionary嗎(這邊這邊)?這幾個原生的資料格式很好用沒錯。但是若要用來進行data science的分析會非常麻煩。所以就有了Pandas這個套件來讓大家可以快速且簡單的利用你手邊的資料。

這邊的教學裡面會用到pandas,所以要在程式的最前面import pandas as pd這個套件,並把這個套件取作pd。接著就可以開始使用pandas拉~

1.Series:

這邊先在l這個變數中儲存list。然後利用pd.Serieslist轉換成Series的形式儲存起來。

l = [1,2,3,'tinycorner',3.14]
s = pd.Series(l)

接著我們來看看變數ls裡面存了什麼啊?可以看到l的確是list的格式,而s呢?就是list重新加入索引值,變成新的檔案格式。為什麼要這樣呢????其實可以想像一下在成功嶺受訓的時候,要穿上很白癡的號碼衣,為什麼要做這個白癡的事情呢?因為大家都是死光頭,分隊長根本搞不清楚誰是誰,所以阿~當穿上號碼衣之後,他就只要叫號碼就好了。Series也是,未來資料量變大的時候,我們需要藉由索引值來找出所要的資料即可。

接著來看看要怎麼利用索引值叫資料出來。

我們只要在儲存的資料後面加上他的索引值就好。所以像是s[3]就會叫出對應的tinycorner字串出來。想像是分隊長叫98號出列,就會有一個穿著98號號碼衣的人很悲慘的出來…

2.DataFrame:

接著才要開始進入Data science的重頭戲—DataFrame,基本上呢,我們的資料是不可能只有一行,最普通最普通的資料至少要有行跟列。所以這邊我們就需要使用DataFrame來完成這樣的需求囉~~

下面就開始實做拉,我們先嘗試看看要怎麼做出一個班級的成績表

name = ['Bob', 'Tom', 'Jason', 'Marry', 'Julia']
subject = ['Chinese', 'Math', 'Science', 'Music', 'PE', 'History']
df = pd.DataFrame(index=name, columns = subject)
df

這邊我先用list儲存namesubject。接著利用DataFrame來創建下面的格式,並且設定變index還有columns分別使用namesubject,並將它存到df當中。大家可以看下面輸出結果,我們要的名字科目的格式就會生成出來啦~

不過大家有沒有發現上面出現了NaN,在Python裡面,若是你沒有把數值存到裡面的話,Python會自動把他記成NaN,代表”沒有”或是”缺失值”,注意喔!!!這邊NaN不等於”0″,舉例來說,你因為生病缺考跟考零分是不一樣的意思。未來TinyCorner也會教如果遇到NaN的話該怎麼處理,這邊我們就把數值給填進去完成這張表吧~

scores = [[ 52,85,96,100,75,54],[40,98,93,54,33,20],[100,97,54,55,100,88],
          [72,67,64,53,87,83],[45,90,100,55,34,96]]
df = pd.DataFrame(scores, index = name, columns = subject)
df

這邊我們使用很多個清單把學生的分數儲存起來,在scores中,有很多個list,每個list都代表一個學生全部科目的分數(也就是每個list會代表一行的資料)。最後再把indexcolumns放上去表格,就是一張漂亮的同學的各科成績資料囉~

好啦~有了成績表之後,接著我會教大家怎麼用使用DataFrame裡面更細部的功能,並看看我們能不能從這張表格裡面挖出什麼有用的資訊吧。

 

 

 

 

元組( tuple )、列表( list )、字典( dictionary ) 儲存資料三兄弟

在前面的文章有提到,Python 會自動幫你指定變數的型態,這對 coding 的人來說是一個方便的事情。然而,這樣子會產生一個問題,可能到到後面你無法確定現在變數的型態是什麼?所以 Python 內建了一個函數可以讓你查詢變數的型態type,試試看以下程式碼:

test_1=5
test_2=2.3
test_3='apple'
print(type(test_1))
print(type(test_2))
print(type(test_3))

在前面三行,我們分別將test_1,test_2,test_3分別儲存一個整數、浮點數與字串;後面三行利用type找出類型,並使用print將它們顯示在螢幕上。

下面三行的執行結果的確驗證了三個變數分別為整數、浮點數和字串。

接下來要介紹Python中,將多個值儲存到一個變數的方法,總共有三種:
1.元組tuple:

tuple有什麼特性呢?他有點像是那種刻在石板上的戒律。tuple一旦儲存起來,就無法做更動了,所以適合儲存那些不想要變動的值。以免不小心更改到值。

x = (1, 'apple', 2, 'banana')
print(type(x))
print(x)

要使用元組(tuple)方式儲存的話,使用括號”()”將要儲存的數值刮起來,每組資料用”,”分隔開來,另外元組可以儲存不同的變數型態。若是利用type再次確認x的型態,會發現的確是tuple

2.列表list:

list的操作在 Python 中算是最常見也是最基礎的方式。簡單來說,他就是把一連串的資料,不管青紅皂白的儲存起來。比較需要注意的地方,在於你叫呼叫出list中的值,要搞清楚他的索引值。未來我會寫一篇關於操作list更詳細的介紹。

y = [1, 'apple', 2, 'banana']
print(type(y))
print(y)

想要使用list儲存,使用中括號”[]”,並用”,”分隔開來,而且他裡面可以放入不同種類形式的資料。使用剛剛學到的type做確認,沒錯,果然是list的型態

3.字典dictionary:

dictionary的儲存方式,大家可以想像成英文單字卡本,也就是一面可以寫中文,一面可以寫英文的那種本子。他多了一個”鍵值”,他會跟你的資料做綁定,也就是你可以藉由鍵值來呼叫他所代表的資料。

dictionary的儲存方式利用”{}”,在並且一個鍵值和資料用”:”分隔,每一組使用”,”分隔。使用的方式如下

z = {"apple":"蘋果", "banana":"香蕉", "one":1}
print(type(z))
print(z["apple"])
print(z["banana"])
print(z["one"])

可以看到你對於每個鍵值做查詢的話,可以看到他所儲存的值。這種儲存方式適合兩兩一組的值,而且dictionary可以在事後做更改、新增跟刪除。

呼~先初步介紹 Python 中的三種資料型態儲存方式,接著會詳細介紹三種資料形態要怎麼操作與應用~~