旗下產(chǎn)業(yè): A產(chǎn)業(yè)/?A實(shí)習(xí)/?A計(jì)劃
全國(guó)統(tǒng)一咨詢熱線:010-5367 2995
首頁(yè) > 熱門文章 > 大數(shù)據(jù)分析 > 大數(shù)據(jù)分析Python建立分析數(shù)據(jù)管道

大數(shù)據(jù)分析Python建立分析數(shù)據(jù)管道

時(shí)間:2020-05-18來(lái)源:5wd995.cn點(diǎn)擊量:作者:Sissi
時(shí)間:2020-05-18點(diǎn)擊量:作者:Sissi



  如果您曾經(jīng)想通過(guò)流數(shù)據(jù)或快速變化的數(shù)據(jù)在線學(xué)習(xí)Python,那么您可能會(huì)熟悉數(shù)據(jù)管道的概念。數(shù)據(jù)管道允許您通過(guò)一系列步驟將數(shù)據(jù)從一種表示形式轉(zhuǎn)換為另一種表示形式。數(shù)據(jù)管道是數(shù)據(jù)工程的關(guān)鍵部分,我們將在新的“ 數(shù)據(jù)工程師之路”中進(jìn)行講授。在本教程中,我們將逐步使用Python和SQL建立數(shù)據(jù)管道。
 

  數(shù)據(jù)管道的一個(gè)常見(jiàn)用例是找出有關(guān)您網(wǎng)站訪問(wèn)者的信息。如果您熟悉Google Analytics(分析),那么您就會(huì)知道查看訪問(wèn)者的實(shí)時(shí)和歷史信息的價(jià)值。在此博客文章中,我們將使用Web服務(wù)器日志中的數(shù)據(jù)來(lái)回答有關(guān)訪問(wèn)者的問(wèn)題。
 

  如果您不熟悉,則每次訪問(wèn)網(wǎng)頁(yè)(例如Dataquest Blog)時(shí),都會(huì)從Web服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù)。要托管此博客,我們使用一個(gè)稱為Nginx的高性能Web服務(wù)器。輸入網(wǎng)址并查看結(jié)果的過(guò)程如下:
 

大數(shù)據(jù)分析
 

  從Web瀏覽器向服務(wù)器發(fā)送請(qǐng)求的過(guò)程。
 

  首先,客戶端向Web服務(wù)器發(fā)送請(qǐng)求以請(qǐng)求某個(gè)頁(yè)面。然后,Web服務(wù)器從文件系統(tǒng)加載頁(yè)面并將其返回給客戶端(Web服務(wù)器也可以動(dòng)態(tài)生成頁(yè)面,但是我們現(xiàn)在不必?fù)?dān)心這種情況)。Web服務(wù)器在處理請(qǐng)求時(shí),在文件系統(tǒng)上的日志文件中寫入一行,其中包含有關(guān)客戶端和請(qǐng)求的一些元數(shù)據(jù)。該日志使某人可以稍后查看誰(shuí)在什么時(shí)間訪問(wèn)了網(wǎng)站上的哪些頁(yè)面,并執(zhí)行其他分析。
 

  以下是此博客的Nginx日志中的幾行:

大數(shù)據(jù)分析
 

  每個(gè)請(qǐng)求都是一行,隨著對(duì)服務(wù)器的請(qǐng)求,行按時(shí)間順序追加。每行的格式是Nginx combined格式,內(nèi)部看起來(lái)像這樣:

大數(shù)據(jù)分析
 

  請(qǐng)注意,日志格式使用的變量,例如$remote_addr,之后將被特定請(qǐng)求的正確值替換。以下是日志格式的每個(gè)變量的說(shuō)明:

  a.$remote_addr—向服務(wù)器發(fā)出請(qǐng)求的客戶端的IP地址。對(duì)于日志的第一行,這是X.X.X.X(出于隱私目的,我們刪除了ips)。

  b.$remote_user—如果客戶端通過(guò)基本身份驗(yàn)證進(jìn)行了身份驗(yàn)證,則為用戶名。在第一條日志行中為空白。

  c.$time_local—發(fā)出請(qǐng)求的當(dāng)?shù)貢r(shí)間。09/Mar/2017:01:15:59 +0000在第一行。

  d.$request— 請(qǐng)求的類型,以及發(fā)出請(qǐng)求的URL。GET /blog/assets/css/jupyter.css HTTP/1.1在第一行。

  e.$status— 來(lái)自服務(wù)器的響應(yīng)狀態(tài)代碼。200在第一行。

  f.$body_bytes_sent—服務(wù)器在響應(yīng)正文中發(fā)送給客戶端的字節(jié)數(shù)。30294在第一行。

  g.$http_referrer—在發(fā)送當(dāng)前請(qǐng)求之前客戶端所在的頁(yè)面。https://www.dataquest.io/blog/在第一行。

  h.$http_user_agent—有關(guān)客戶端的瀏覽器和系統(tǒng)的信息。Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36 PingdomPageSpeed/1.0 (pingbot/2.0; +http://www.pingdom.com/)在第一行。
 

  隨著對(duì)它的更多請(qǐng)求,Web服務(wù)器不斷向日志文件添加行。有時(shí),Web服務(wù)器會(huì)旋轉(zhuǎn)過(guò)大的日志文件,并存檔舊數(shù)據(jù)。
 

  可以想象,公司通過(guò)了解哪些訪客在他們的網(wǎng)站上以及他們?cè)谧鍪裁炊@得了很多價(jià)值。例如,意識(shí)到使用Google Chrome瀏覽器的用戶很少訪問(wèn)某個(gè)頁(yè)面,可能表明該頁(yè)面在該瀏覽器中存在渲染問(wèn)題。
 

  另一個(gè)例子是知道每天有多少國(guó)家的用戶訪問(wèn)您的網(wǎng)站。它可以幫助您確定將市場(chǎng)營(yíng)銷重點(diǎn)放在哪些國(guó)家。在最簡(jiǎn)單的層面上,僅了解您每天有多少訪問(wèn)者就可以幫助您了解營(yíng)銷工作是否正常進(jìn)行。
 

  為了計(jì)算這些指標(biāo),我們需要解析日志文件并進(jìn)行分析。為此,我們需要構(gòu)建一個(gè)數(shù)據(jù)管道。
 

  關(guān)于數(shù)據(jù)管道的思考
 

  這是一個(gè)數(shù)據(jù)管道的簡(jiǎn)單示例,該數(shù)據(jù)管道計(jì)算每天有多少訪問(wèn)者訪問(wèn)該站點(diǎn):

大數(shù)據(jù)分析

  每天從原始日志獲取訪問(wèn)者計(jì)數(shù)。

  正如您在上面看到的,我們從原始日志數(shù)據(jù)轉(zhuǎn)到儀表板,在該儀表板中我們可以查看每天的訪客數(shù)。請(qǐng)注意,該管道連續(xù)運(yùn)行-將新條目添加到服務(wù)器日志時(shí),它將捕獲它們并進(jìn)行處理。關(guān)于我們?nèi)绾螛?gòu)建管道,您希望已經(jīng)注意到一些事情:

  a.每個(gè)管道組件都彼此分開(kāi),并接受定義的輸入,并返回定義的輸出。

  b.盡管此處未顯示,但可以將這些輸出緩存或保留以進(jìn)行進(jìn)一步分析。

  c.我們將原始日志數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中。這樣可以確保,如果我們要進(jìn)行其他分析,則可以訪問(wèn)所有原始數(shù)據(jù)。

  d.我們刪除重復(fù)的記錄。在分析過(guò)程中引入重復(fù)數(shù)據(jù)非常容易,因此在通過(guò)管道傳遞數(shù)據(jù)之前進(jìn)行重復(fù)數(shù)據(jù)刪除至關(guān)重要。

  e.每個(gè)管道組件將數(shù)據(jù)饋送到另一個(gè)組件。我們希望使每個(gè)組件盡可能小,以便我們可以分別按比例放大管道組件,或?qū)⑤敵鲇糜诓煌愋偷姆治觥?/p>

  現(xiàn)在,我們已經(jīng)了解了該管道的高層情況,讓我們?cè)赑ython中實(shí)現(xiàn)它。

  處理和存儲(chǔ)Web服務(wù)器日志

  為了創(chuàng)建數(shù)據(jù)管道,我們需要訪問(wèn)Web服務(wù)器日志數(shù)據(jù)。我們創(chuàng)建了一個(gè)腳本,該腳本將連續(xù)生成偽造(但有些現(xiàn)實(shí))的日志數(shù)據(jù)。這是如何遵循這篇文章:

  a.克隆此倉(cāng)庫(kù)。

  b.請(qǐng)按照自述文件安裝Python要求。

  c.運(yùn)行python log_generator.py。

  運(yùn)行腳本后,您應(yīng)該看到新條目被寫入log_a.txt同一文件夾中。100寫入行后log_a.txt,腳本將旋轉(zhuǎn)到log_b.txt。它將保持每100行在文件之間來(lái)回切換。

  啟動(dòng)腳本后,我們只需要編寫一些代碼來(lái)提取(或讀入)日志。該腳本將需要:

  a.打開(kāi)日志文件并逐行讀取它們。

  b.將每一行解析為字段。

  c.將每一行和已解析的字段寫入數(shù)據(jù)庫(kù)。

  d.確保沒(méi)有將重復(fù)的行寫入數(shù)據(jù)庫(kù)。

  如果要繼續(xù),此 代碼位于此存儲(chǔ)庫(kù)的store_logs.py文件中。

  為了實(shí)現(xiàn)我們的第一個(gè)目標(biāo),我們可以打開(kāi)文件并繼續(xù)嘗試從文件中讀取行。

  以下代碼將:

  a.在讀取模式下打開(kāi)兩個(gè)日志文件。

  b.永遠(yuǎn)循環(huán)。

  c.找出兩個(gè)文件當(dāng)前正在讀取的字符在哪里(使用tell方法)。

  d.嘗試從兩個(gè)文件中讀取一行(使用readline方法)。

  e.如果兩個(gè)文件均未寫入任何行,請(qǐng)稍睡片刻,然后重試。

  f.在睡覺(jué)之前,將讀取點(diǎn)設(shè)置回我們?cè)瓉?lái)的位置(在調(diào)用之前readline),以使我們不會(huì)錯(cuò)過(guò)任何事情(使用seek方法)。

  g.如果其中一個(gè)文件寫入了一行,請(qǐng)抓住該行?;叵胍幌乱淮沃荒軐懭胍粋€(gè)文件,因此我們無(wú)法從兩個(gè)文件中獲取行。



 

  讀完日志文件后,我們需要進(jìn)行一些非?;镜慕馕觯詫⑵洳鸱譃槎鄠€(gè)字段。我們不想在這里做任何花哨的事情-我們可以將其保存下來(lái),以供以后的步驟使用。通常,您希望管道中的第一步(保存原始數(shù)據(jù)的第一步)盡可能輕巧,因此發(fā)生故障的機(jī)會(huì)很小。如果此步驟在任何時(shí)候都失敗了,您將最終丟失一些原始數(shù)據(jù),這些原始數(shù)據(jù)將無(wú)法恢復(fù)!
 

  為了使解析簡(jiǎn)單,我們將在空格()字符上進(jìn)行拆分,然后進(jìn)行一些重組:

大數(shù)據(jù)分析
 

  將日志文件解析為結(jié)構(gòu)化字段。

  在下面的代碼中,我們:

  a.取一條日志行,并在空格字符()上進(jìn)行分割。

  b.從拆分表示中提取所有字段。

  c.請(qǐng)注意,某些字段在這里看起來(lái)不是“完美”的-例如,時(shí)間仍會(huì)帶有括號(hào)。
  d.初始化一個(gè)created變量,該變量存儲(chǔ)創(chuàng)建數(shù)據(jù)庫(kù)記錄的時(shí)間。這將使將來(lái)的管道步驟可以查詢數(shù)據(jù)。

大數(shù)據(jù)分析
 

  我們還需要為我們的SQLite數(shù)據(jù)庫(kù)表確定一個(gè)架構(gòu),并運(yùn)行所需的代碼來(lái)創(chuàng)建它。因?yàn)槲覀兿M私M件簡(jiǎn)單,所以最好使用簡(jiǎn)單的架構(gòu)。我們將使用以下查詢創(chuàng)建表:

大數(shù)據(jù)分析
 

  請(qǐng)注意我們?nèi)绾未_保每個(gè)記錄raw_log都是唯一的,因此我們避免重復(fù)記錄。另外,請(qǐng)注意我們?nèi)绾螌⑺幸呀馕龅淖侄闻c原始日志一起插入數(shù)據(jù)庫(kù)。有一個(gè)論點(diǎn)是我們不應(yīng)該插入已解析的字段,因?yàn)槲覀兛梢暂p松地再次計(jì)算它們。但是,將它們添加到字段中會(huì)使將來(lái)的查詢變得更加容易(例如,我們可以僅選擇time_local列),并且節(jié)省了下一行的計(jì)算工作量。
 

  保留原始日志對(duì)我們很有幫助,以防萬(wàn)一我們需要一些我們未提取的信息,或者以后各行中字段的順序變得很重要。由于這些原因,存儲(chǔ)原始數(shù)據(jù)始終是一個(gè)好主意。
 

  最后,我們需要將已解析的記錄插入SQLite數(shù)據(jù)庫(kù)的logs表中。選擇一個(gè)數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)此類數(shù)據(jù)非常關(guān)鍵。在這種情況下,我們選擇SQLite是因?yàn)樗芎?jiǎn)單,并將所有數(shù)據(jù)存儲(chǔ)在一個(gè)文件中。如果您更關(guān)心性能,那么使用Postgres這樣的數(shù)據(jù)庫(kù)可能會(huì)更好。
 

  在下面的代碼中,我們:

  a.連接到SQLite數(shù)據(jù)庫(kù)。

  b.實(shí)例化游標(biāo)以執(zhí)行查詢。

  c.將所有我們將插入表中的值放在一起(parsed是我們之前解析的值的列表)

  d.將值插入數(shù)據(jù)庫(kù)。

  e.提交事務(wù),以便將其寫入數(shù)據(jù)庫(kù)。

  f.關(guān)閉與數(shù)據(jù)庫(kù)的連接。

大數(shù)據(jù)分析
 

  我們剛剛完成了產(chǎn)品開(kāi)發(fā)的第一步!現(xiàn)在,我們已經(jīng)存儲(chǔ)了重復(fù)數(shù)據(jù)刪除的數(shù)據(jù),接下來(lái)我們可以繼續(xù)統(tǒng)計(jì)訪問(wèn)者了。
 

  用數(shù)據(jù)管道統(tǒng)計(jì)訪問(wèn)者
 

  我們可以使用幾種不同的機(jī)制在流水線步驟之間共享數(shù)據(jù):
 

  a.檔案

  b.資料庫(kù)

  c.Queue列
 

  在每種情況下,我們都需要一種從當(dāng)前步驟到下一步獲取數(shù)據(jù)的方法。如果將下一步(按天統(tǒng)計(jì)ip)指向數(shù)據(jù)庫(kù),則可以根據(jù)時(shí)間查詢添加事件,從而提取事件。盡管通過(guò)使用隊(duì)列將數(shù)據(jù)傳遞到下一步將獲得更高的性能,但目前性能并不重要。
 

  我們將創(chuàng)建另一個(gè)文件count_visitors.py,并添加一些將數(shù)據(jù)從數(shù)據(jù)庫(kù)中拉出并按天進(jìn)行計(jì)數(shù)的代碼。
 

  我們首先要從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)。在下面的代碼中,我們:

  a.連接到數(shù)據(jù)庫(kù)。

  b.查詢?cè)谀硞€(gè)時(shí)間戳記之后添加的任何行。

  c.提取所有行。

大數(shù)據(jù)分析
 

  然后,我們需要一種從查詢的每一行中提取IP和時(shí)間的方法。以下代碼將:
 

  a.初始化兩個(gè)空列表。

  b.從查詢響應(yīng)中提取時(shí)間和IP,并將其添加到列表中。

大數(shù)據(jù)分析
 

  您可能會(huì)注意到,在上面的代碼中,我們將時(shí)間從字符串解析為datetime對(duì)象。解析代碼如下:

大數(shù)據(jù)分析
 

  整理好片段后,我們只需要一種從數(shù)據(jù)庫(kù)中提取新行并將其添加到每天訪問(wèn)量中的方法。以下代碼將:
 

  a.根據(jù)給定的開(kāi)始時(shí)間從數(shù)據(jù)庫(kù)中獲取行以進(jìn)行查詢(我們將獲取在給定時(shí)間之后創(chuàng)建的所有行)。

  b.datetime從行中 提取IP和對(duì)象。

  c.如果有任何行,請(qǐng)將開(kāi)始時(shí)間指定為我們有一行的最晚時(shí)間。這樣可以防止我們多次查詢同一行。

  d.創(chuàng)建一個(gè)密鑰,day用于計(jì)算唯一IP。

  e.將每個(gè)ip添加到每天僅包含唯一ip的集合中。

大數(shù)據(jù)分析
 

  此代碼將確保unique_ips每天都有一個(gè)密鑰,并且值將是一組設(shè)置,其中包含當(dāng)天到達(dá)該站點(diǎn)的所有唯一ip。
 

  每天對(duì)ip進(jìn)行分類后,我們只需要進(jìn)行一些計(jì)數(shù)即可。在下面的代碼中,我們:
 

  a.將每天的訪問(wèn)者數(shù)量分配給counts。

  b.從中提取元組列表counts。

  c.對(duì)列表進(jìn)行排序,以便按順序排列日期。

  d.打印出每天的訪客計(jì)數(shù)。

大數(shù)據(jù)分析
 

  然后,我們可以從上方獲取代碼段,以便它們每秒鐘運(yùn)行一次5:

大數(shù)據(jù)分析
 

  共同努力
 

  現(xiàn)在,我們?yōu)g覽了一個(gè)腳本以生成日志,并通過(guò)兩個(gè)管道步驟來(lái)分析日志。為了使完整的管道運(yùn)行:
 

  a.如果還沒(méi)有,請(qǐng)從Github 復(fù)制analytics_pipeline存儲(chǔ)庫(kù)。

  b.按照README.md文件進(jìn)行所有設(shè)置。

  c.執(zhí)行l(wèi)og_generator.py。

  d.執(zhí)行store_logs.py。

  e.執(zhí)行count_visitors.py。
 

  運(yùn)行后count_visitors.py,您應(yīng)該看到每秒打印出當(dāng)天的訪客計(jì)數(shù)5。如果您將腳本運(yùn)行幾天,就會(huì)開(kāi)始看到訪客數(shù)天。
 

  恭喜你!您已經(jīng)設(shè)置并運(yùn)行數(shù)據(jù)管道?,F(xiàn)在讓我們創(chuàng)建另一個(gè)從數(shù)據(jù)庫(kù)中提取的管道步驟。
 

  向數(shù)據(jù)管道添加另一個(gè)步驟

大數(shù)據(jù)分析
 

  將管道分成多個(gè)部分的主要好處之一是,很容易將一步的輸出用于另一目的。讓我們?cè)囍愠鲈L問(wèn)每個(gè)網(wǎng)站的瀏覽者的人數(shù),而不是計(jì)算訪問(wèn)者的人數(shù)。這將使我們的管道如下所示:
 

  現(xiàn)在,我們有一個(gè)管道步驟驅(qū)動(dòng)兩個(gè)下游步驟。
 

  如您所見(jiàn),一步轉(zhuǎn)換的數(shù)據(jù)可以是兩個(gè)不同步的輸入數(shù)據(jù)。如果要遵循此流水線步驟,則應(yīng)查看count_browsers.py克隆的存儲(chǔ)庫(kù)中的文件。
 

  為了對(duì)瀏覽器進(jìn)行計(jì)數(shù),我們的代碼與計(jì)數(shù)訪客的代碼基本保持不變。主要區(qū)別在于我們解析用戶代理以檢索瀏覽器的名稱。在下面的代碼中,您會(huì)注意到我們查詢的是http_user_agent列而不是remote_addr,并且我們解析了用戶代理以找出訪問(wèn)者正在使用的瀏覽器:

大數(shù)據(jù)分析
 

  然后,我們修改循環(huán)以統(tǒng)計(jì)訪問(wèn)該網(wǎng)站的瀏覽器:

大數(shù)據(jù)分析
 

  進(jìn)行這些更改后,我們便python count_browsers.py可以計(jì)算出有多少瀏覽器正在訪問(wèn)我們的網(wǎng)站。
 

  現(xiàn)在,我們已經(jīng)創(chuàng)建了兩個(gè)基本數(shù)據(jù)管道,并演示了數(shù)據(jù)管道的一些關(guān)鍵原理:
 

  a.使每個(gè)步驟都很小。

  b.使用定義的接口在管道之間傳遞數(shù)據(jù)。

  c.存儲(chǔ)所有原始數(shù)據(jù)以供以后分析。

  擴(kuò)展數(shù)據(jù)管道
 

  在完成此數(shù)據(jù)管道教程之后,您應(yīng)該了解如何使用Python創(chuàng)建基本數(shù)據(jù)管道。但是現(xiàn)在不要停止!隨意擴(kuò)展我們實(shí)施的管道。這里有一些想法:
 

  a.您可以建立一個(gè)可以處理更多數(shù)據(jù)的管道嗎?如果連續(xù)生成日志消息怎么辦?

  b.您可以對(duì)IP進(jìn)行地理位置定位以找出訪問(wèn)者在哪里嗎?

  c.您能找出哪些網(wǎng)頁(yè)最常被點(diǎn)擊嗎?

  如果您有權(quán)訪問(wèn)真實(shí)的Web服務(wù)器日志數(shù)據(jù),則可能還需要在該數(shù)據(jù)上嘗試其中一些腳本,以查看是否可以計(jì)算出任何有趣的指標(biāo)。

  是否想通過(guò)交互式深入的數(shù)據(jù)工程課程將您的技能提升到一個(gè)新的水平?試試我們的數(shù)據(jù)工程師之路,它可以幫助您從頭開(kāi)始學(xué)習(xí)數(shù)據(jù)工程。



 

預(yù)約申請(qǐng)免費(fèi)試聽(tīng)課

填寫下面表單即可預(yù)約申請(qǐng)免費(fèi)試聽(tīng)!怕錢不夠?可先就業(yè)掙錢后再付學(xué)費(fèi)! 怕學(xué)不會(huì)?助教全程陪讀,隨時(shí)解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可推薦就業(yè)!

?2007-2021/北京漫動(dòng)者教育科技有限公司版權(quán)所有
備案號(hào):京ICP備12034770號(hào)

?2007-2022/ 5wd995.cn 北京漫動(dòng)者數(shù)字科技有限公司 備案號(hào): 京ICP備12034770號(hào) 監(jiān)督電話:010-53672995 郵箱:bjaaa@aaaedu.cc

京公網(wǎng)安備 11010802035704號(hào)

網(wǎng)站地圖