摘要:接著馬上想到自己網(wǎng)站的訪問日志不就是現(xiàn)成的優(yōu)質(zhì)數(shù)據(jù)源嗎于是愉快的決定寫個腳本統(tǒng)計一下訪問日志中的信息。腳本目前有三個功能找出所有的信息并排序統(tǒng)計操作系統(tǒng)數(shù)據(jù)統(tǒng)計瀏覽器數(shù)據(jù)。
轉(zhuǎn)載請注明文章出處:https://tlanyan.me/stat-user-...
即將用到爬蟲,于是打算收集一下User Agent(UA)數(shù)據(jù)。接著馬上想到自己網(wǎng)站的訪問日志不就是現(xiàn)成的優(yōu)質(zhì)數(shù)據(jù)源嗎?于是愉快的決定寫個腳本統(tǒng)計一下Nginx訪問日志中的UA信息。
這類簡單操作,用腳本語言就足夠,毫無疑問肯定要用最熟悉的PHP。打開vim就開擼,十幾分鐘下來,功能簡單的統(tǒng)計腳本就搞定了。
腳本目前有三個功能:1. 找出所有的UA信息并排序; 2. 統(tǒng)計操作系統(tǒng)數(shù)據(jù); 3. 統(tǒng)計瀏覽器數(shù)據(jù)。程序運行截圖如下:
UA信息
操作系統(tǒng)信息
瀏覽器
用腳本統(tǒng)計最近一個月的訪問日志,得到以下結(jié)果:
搜索引擎爬蟲比較頻繁,每天有好幾千次數(shù)據(jù)訪問;
Windows仍是份額最大的操作系統(tǒng),Linux桌面依然份額很小;
Chrome目前是瀏覽器領(lǐng)域的霸主,其次是Firefox,Opera已經(jīng)很小眾了。
最后附上PHP腳本的代碼,也可以從本人的Github里找到:https://github.com/tlanyan/Sc...
#!/usr/bin/php * @link http://tlanyan.me */ /* vim: set ts=4; set sw=4; set ss=4; set expandtab; */ function getFileList(string $path) : array { return glob(rtrim($path, "/") . "/*access.log*"); } function statFiles(array $files) : array { $stat = []; echo PHP_EOL, "start to read files...", PHP_EOL; foreach ($files as $file) { echo "read file: $file ...", PHP_EOL; $contents = getFileContent($file); foreach ($contents as $line) { $ua = getUA($line); if (isset($stat[$ua])) { $stat[$ua] += 1; } else { $stat[$ua] = 1; } } } echo "stat all files done!", PHP_EOL, PHP_EOL; return $stat; } function getFileContent(string $file) : array { if (substr($file, -3, 3) === ".gz") { return gzfile($file); } return file($file); } function getUA(string $line) : ?string { // important! Nginx log format determins the UA location in the line! // You may have to refactor following codes to get the right result // UA starts from fifth double quote $count = 0; $offset = 0; while ($count < 5) { $pos = strpos($line, """, $offset); if ($pos === false) { echo "Error! Unknown line: $line", PHP_EOL; return null; } $count ++; $offset = $pos + 1; } $end = strpos($line, """, $offset); return substr($line, $offset, $end - $offset); } function usage() { echo "Usage: php statUA.php [option] [dir]", PHP_EOL; echo " options:", PHP_EOL; echo " -h: show this help", PHP_EOL; echo " -v: verbose mode", PHP_EOL; echo "-n NUM: UA list number", PHP_EOL; echo " dir: directory to the log files", PHP_EOL; echo PHP_EOL; } function filterUA(array& $stat, array $UAFilters) { $filterCount = 0; foreach ($UAFilters as $filter) { foreach ($stat as $ua => $count) { if (stripos($ua, $filter) !== false) { $filterCount += $count; unset($stat[$ua]); } } } echo "filter $filterCount records!", PHP_EOL; } function printCount(array $stat) { $sum = array_sum($stat); foreach ($stat as $key => $count) { echo $key, " : ", $count, ", percent: ", sprintf("%.2f", 100*$count/$sum), PHP_EOL; } } function statOS(array $UAs) : array { global $debug; echo PHP_EOL, "stat OS...", PHP_EOL; $os = ["Windows", "MacOS", "Linux", "Android", "iOS", "other"]; $stat = array_fill_keys($os, 0); foreach ($UAs as $key => $count) { if (strpos($key, "Windows") !== false) { $stat["Windows"] += $count; } else if (strpos($key, "Macintosh") !== false) { $stat["MacOS"] += $count; // must deal Android first, then Linux } else if (strpos($key, "Android") !== false) { $stat["Android"] += $count; } else if (strpos($key, "Linux") !== false) { $stat["Linux"] += $count; } else if (strpos($key, "iPhone") !== false || strpos($key, "iOS") !== false || strpos($key, "like Mac OS") !== false || strpos($key, "Darwin") !== false) { $stat["iOS"] += $count; } else { if ($debug) { echo "other: $key, count: $count", PHP_EOL; } $stat["other"] += $count; } } return $stat; } function statBrowser(array $UAs) : array { global $debug; echo PHP_EOL, "stat brwoser...", PHP_EOL; $browsers = ["Chrome", "Firefox", "IE", "Safari", "Edge", "Opera", "other"]; $stat = array_fill_keys($browsers, 0); foreach ($UAs as $key => $count) { if (strpos($key, "MSIE") !== false) { $stat["IE"] += $count; } else if (strpos($key, "Edge") !== false) { $stat["Edge"] += $count; } else if (strpos($key, "Firefox") !== false) { $stat["Firefox"] += $count; } else if (strpos($key, "OPR") !== false) { $stat["Opera"] += $count; // first Chrome, then Safari } else if (strpos($key, "Chrome") !== false) { $stat["Chrome"] += $count; } else if (strpos($key, "Safari") !== false) { $stat["Safari"] += $count; } else { if ($debug) { echo "other: $key, count: $count", PHP_EOL; } $stat["other"] += $count; } } return $stat; } function parseCmd() { global $debug, $num, $path, $argc, $argv; $optind = null; $options = getopt("hvn:", [], $optind); if ($argc > 2 && empty($options)) { usage(); exit(1); } if (isset($options["h"])) { usage(); exit(0); } if (isset($options["v"])) { $debug = true; } if (isset($options["n"])) { $num = intval($options["n"]); if ($num <= 0) { $num = 10; } } if ($argc === 2 && empty($options)) { $path = $argv[1]; } if ($argc > $optind) { $path = $argv[$optind]; } if (!is_dir($path)) { echo "invalid directory: $path", PHP_EOL; exit(1); } if ($debug) { echo "num: $num", PHP_EOL; echo "verbose: ", var_export($debug, true), PHP_EOL; echo "path: $path", PHP_EOL; } } if (version_compare(PHP_VERSION, "7.1") < 0) { exit("scripts require PHP >=7.1"); } $path = "."; $debug = false; $num = 10; $UAFilters = [ "spider", "bot", "wget", "curl", ]; parseCmd(); $files = getFileList($path); if (empty($files)) { echo """ . realpath($path) . "" does not contain access log files.", PHP_EOL; exit(0); } $allUA = statFiles($files); if (empty($allUA)) { echo "no data", PHP_EOL; exit(0); } filterUA($allUA, $UAFilters); // sort array with count uasort($allUA, function ($a, $b) { return $b - $a; }); if ($debug) { print_r($allUA); } echo PHP_EOL, "---- top $num UA ----", PHP_EOL; printCount(array_slice($allUA, 0, $num)); echo "-------------------", PHP_EOL; $os = statOS($allUA); echo PHP_EOL, "os count:", PHP_EOL; printCount($os); $browser = statBrowser($allUA); echo PHP_EOL, "browser count:", PHP_EOL; printCount($browser);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/30974.html
摘要:接著馬上想到自己網(wǎng)站的訪問日志不就是現(xiàn)成的優(yōu)質(zhì)數(shù)據(jù)源嗎于是愉快的決定寫個腳本統(tǒng)計一下訪問日志中的信息。腳本目前有三個功能找出所有的信息并排序統(tǒng)計操作系統(tǒng)數(shù)據(jù)統(tǒng)計瀏覽器數(shù)據(jù)。 轉(zhuǎn)載請注明文章出處:https://tlanyan.me/stat-user-... 即將用到爬蟲,于是打算收集一下User Agent(UA)數(shù)據(jù)。接著馬上想到自己網(wǎng)站的訪問日志不就是現(xiàn)成的優(yōu)質(zhì)數(shù)據(jù)源嗎?于是愉...
摘要:給出的日志等級順序就是記錄最小到最嚴(yán)謹(jǐn)?shù)娜罩镜燃夗樞颉ee誤日志格式不支持自定義日志格式但他同樣記錄當(dāng)前時間日志等級和具體信息等數(shù)據(jù)。日志緩沖區(qū)當(dāng)系統(tǒng)處于負載狀態(tài)時,啟用日志緩沖區(qū)以降低進程阻塞。 原文鏈接: 何曉東 博客 如果想統(tǒng)計網(wǎng)站的訪問來源信息,可以用 php 獲取信息,記錄到數(shù)據(jù)庫的形式,也可以直接使用 nginx 提供的訪問日志,來記錄網(wǎng)站的訪問詳情,管理員可以通過分析 ng...
摘要:給出的日志等級順序就是記錄最小到最嚴(yán)謹(jǐn)?shù)娜罩镜燃夗樞颉ee誤日志格式不支持自定義日志格式但他同樣記錄當(dāng)前時間日志等級和具體信息等數(shù)據(jù)。日志緩沖區(qū)當(dāng)系統(tǒng)處于負載狀態(tài)時,啟用日志緩沖區(qū)以降低進程阻塞。 原文鏈接: 何曉東 博客 如果想統(tǒng)計網(wǎng)站的訪問來源信息,可以用 php 獲取信息,記錄到數(shù)據(jù)庫的形式,也可以直接使用 nginx 提供的訪問日志,來記錄網(wǎng)站的訪問詳情,管理員可以通過分析 ng...
摘要:爬蟲和反爬蟲日益成為每家公司的標(biāo)配系統(tǒng)。本文將描述一種盡量簡單的反爬蟲方案,可以在十幾分鐘內(nèi)解決部分簡單的爬蟲問題,緩解惡意攻擊或者是系統(tǒng)超負荷運行的狀況至于復(fù)雜的爬蟲以及更精準(zhǔn)的防御,需要另外討論。 showImg(https://segmentfault.com/img/bVDYV4?w=800&h=568); 爬蟲和反爬蟲日益成為每家公司的標(biāo)配系統(tǒng)。爬蟲在情報獲取、虛假流量、動態(tài)...
閱讀 2335·2021-11-24 09:39
閱讀 3778·2021-11-19 09:40
閱讀 2152·2021-09-27 13:36
閱讀 1896·2019-08-30 15:44
閱讀 390·2019-08-30 13:52
閱讀 2712·2019-08-30 11:13
閱讀 2170·2019-08-29 16:18
閱讀 1755·2019-08-29 15:43