如何分析部落格中最流行的程式語言
摘要:這篇文章我們將對一些各種各樣的部落格的流行度相對於他們在谷歌上的排名進行一個分析。所有程式碼可以在 github 上找到。
想法來源
我一直在想,各種各樣的部落格每天到底都有多少頁面瀏覽量,以及在部落格閱讀受眾中最受歡迎的是什麼程式語言。我也很感興趣的是,它們在谷歌的網站排名是否與它們的受歡迎程度直接相關。
為了回答這些問題,我決定做一個 Scrapy 專案,它將收集一些資料,然後對所獲得的資訊執行特定的資料分析和資料視覺化。
第一部分:Scrapy
我們將使用 Scrapy 為我們的工作,因為它為抓取和對該請求處理後的反饋進行管理提供了乾淨和健壯的框架。我們還將使用 Splash 來解析需要處理的 Javascript 頁面。Splash 使用自己的 Web 伺服器充當代理,並處理 Javascript 響應,然後再將其重定向到我們的爬蟲程式。
我這裡沒有描述 Scrapy 的設定,也沒有描述 Splash 的整合。你可以在這裡找到 Scrapy 的示例,而這裡還有 Scrapy+Splash 指南。
獲得相關的部落格
第一步顯然是獲取資料。我們需要關於程式設計部落格的谷歌搜尋結果。你看,如果我們開始僅僅用谷歌自己來搜尋,比如說查詢 “Python”,除了部落格,我們還會得到很多其它的東西。我們需要的是做一些過濾,只留下特定的部落格。幸運的是,有一種叫做 Google 自定義搜尋引擎(CSE)的東西,它能做到這一點。還有一個網站 www.blogsearchengine.org,它正好可以滿足我們需要,它會將使用者請求委託給 CSE,這樣我們就可以檢視它的查詢並重複利用它們。
所以,我們要做的是到 www.blogsearchengine.org 網站,搜尋 “python”,並在一側開啟 Chrome 開發者工具中的網路標籤頁。這截圖是我們將要看到的:
突出顯示的是 blogsearchengine 向谷歌委派的一個搜尋請求,所以我們將複製它,並在我們的 scraper 中使用。
這個部落格抓取爬行器類會是如下這樣的:
class BlogsSpider(scrapy.Spider):
name = 'blogs'
allowed_domains = ['cse.google.com']
def __init__(self, queries):
super(BlogsSpider, self).__init__()
self.queries = queries
與典型的 Scrapy 爬蟲不同,我們的方法覆蓋了 __init__
方法,它接受額外的引數 queries
,它指定了我們想要執行的查詢列表。
現在,最重要的部分是構建和執行這個實際的查詢。這個過程放在 start_requests
爬蟲的方法裡面執行,我們愉快地覆蓋它:
def start_requests(self):
params_dict = {
'cx': ['partner-pub-9634067433254658:5laonibews6'],
'cof': ['FORID:10'],
'ie': ['ISO-8859-1'],
'q': ['query'],
'sa.x': ['0'],
'sa.y': ['0'],
'sa': ['Search'],
'ad': ['n9'],
'num': ['10'],
'rurl': [
'http://www.blogsearchengine.org/search.html?cx=partner-pub'
'-9634067433254658%3A5laonibews6&cof=FORID%3A10&ie=ISO-8859-1&'
'q=query&sa.x=0&sa.y=0&sa=Search'
],
'siteurl': ['http://www.blogsearchengine.org/']
}
params = urllib.parse.urlencode(params_dict, doseq=True)
url_template = urllib.parse.urlunparse(
['https', self.allowed_domains[0], '/cse',
'', params, 'gsc.tab=0&gsc.q=query&gsc.page=page_num'])
for query in self.queries:
for page_num in range(1, 11):
url = url_template.replace('query', urllib.parse.quote(query))
url = url.replace('page_num', str(page_num))
yield SplashRequest(url, self.parse, endpoint='render.html',
args={'wait': 0.5})
在這裡你可以看到相當複雜的 params_dict
字典,它控制所有我們之前找到的 Google CSE URL 的引數。然後我們準備好 url_template
裡的一切,除了已經填好的查詢和頁碼。我們對每種程式語言請求 10 頁,每一頁包含 10 個連結,所以是每種語言有 100 個不同的部落格用來分析。
在 42-43
行,我使用一個特殊的類 SplashRequest
來代替 Scrapy 自帶的 Request 類。它封裝了 Splash 庫內部的重定向邏輯,所以我們無需為此擔心。十分整潔。
最後,這是解析程式:
def parse(self, response):
urls = response.css('div.gs-title.gsc-table-cell-thumbnail') \
.xpath('./a/@href').extract()
gsc_fragment = urllib.parse.urlparse(response.url).fragment
fragment_dict = urllib.parse.parse_qs(gsc_fragment)
page_num = int(fragment_dict['gsc.page'][0])
query = fragment_dict['gsc.q'][0]
page_size = len(urls)
for i, url in enumerate(urls):
parsed_url = urllib.parse.urlparse(url)
rank = (page_num - 1) * page_size + i
yield {
'rank': rank,
'url': parsed_url.netloc,
'query': query
}
所有 Scraper 的核心和靈魂就是解析器邏輯。可以有多種方法來理解響應頁面的結構並構建 XPath 查詢字串。您可以使用 Scrapy shell 嘗試並隨時調整你的 XPath 查詢,而不用執行爬蟲。不過我更喜歡視覺化的方法。它需要再次用到谷歌 Chrome 開發人員控制檯。只需右鍵單擊你想要用在你的爬蟲裡的元素,然後按下 Inspect。它將開啟控制檯,並定位到你指定位置的 HTML 原始碼。在本例中,我們想要得到實際的搜尋結果連結。他們的原始碼定位是這樣的:
在檢視這個元素的描述後我們看到所找的 <div>
有一個 .gsc-table-cell-thumbnail
CSS 類,它是 .gs-title
<div>
的子元素,所以我們把它放到響應物件的 css
方法(46
行)。然後,我們只需要得到部落格文章的 URL。它很容易透過'./a/@href'
XPath 字串來獲得,它能從我們的 <div>
直接子元素的 href
屬性找到。(LCTT 譯註:此處圖文對不上)
尋找流量資料
下一個任務是估測每個部落格每天得到的頁面瀏覽量。得到這樣的資料有各種方式,有免費的,也有付費的。在快速搜尋之後,我決定基於簡單且免費的原因使用網站 www.statshow.com 來做。爬蟲將抓取這個網站,我們在前一步獲得的部落格的 URL 將作為這個網站的輸入引數,獲得它們的流量資訊。爬蟲的初始化是這樣的:
class TrafficSpider(scrapy.Spider):
name = 'traffic'
allowed_domains = ['www.statshow.com']
def __init__(self, blogs_data):
super(TrafficSpider, self).__init__()
self.blogs_data = blogs_data
blogs_data
應該是以下格式的詞典列表:{"rank": 70, "url": "www.stat.washington.edu", "query": "Python"}
。
請求構建函式如下:
def start_requests(self):
url_template = urllib.parse.urlunparse(
['http', self.allowed_domains[0], '/www/{path}', '', '', ''])
for blog in self.blogs_data:
url = url_template.format(path=blog['url'])
request = SplashRequest(url, endpoint='render.html',
args={'wait': 0.5}, meta={'blog': blog})
yield request
它相當的簡單,我們只是把字串 /www/web-site-url/
新增到 'www.statshow.com'
URL 中。
現在讓我們看一下語法解析器是什麼樣子的:
def parse(self, response):
site_data = response.xpath('//div[@id="box_1"]/span/text()').extract()
views_data = list(filter(lambda r: '$' not in r, site_data))
if views_data:
blog_data = response.meta.get('blog')
traffic_data = {
'daily_page_views': int(views_data[0].translate({ord(','): None})),
'daily_visitors': int(views_data[1].translate({ord(','): None}))
}
blog_data.update(traffic_data)
yield blog_data
與部落格解析程式類似,我們只是透過 StatShow 示例的返回頁面,然後找到包含每日頁面瀏覽量和每日訪問者的元素。這兩個引數都確定了網站的受歡迎程度,對於我們的分析只需要使用頁面瀏覽量即可 。
第二部分:分析
這部分是分析我們蒐集到的所有資料。然後,我們用名為 Bokeh 的庫來視覺化準備好的資料集。我在這裡沒有給出執行器和視覺化的程式碼,但是它可以在 GitHub repo 中找到,包括你在這篇文章中看到的和其他一切東西。
最初的結果集含有少許偏離過大的資料,(如 google.com、linkedin.com、Oracle.com 等)。它們顯然不應該被考慮。即使其中有些有部落格,它們也不是針對特定語言的。這就是為什麼我們基於這個 StackOverflow 回答 中所建議的方法來過濾異常值。
語言流行度比較
首先,讓我們對所有的語言進行直接的比較,看看哪一種語言在前 100 個部落格中有最多的瀏覽量。
這是能進行這個任務的函式:
def get_languages_popularity(data):
query_sorted_data = sorted(data, key=itemgetter('query'))
result = {'languages': [], 'views': []}
popularity = []
for k, group in groupby(query_sorted_data, key=itemgetter('query')):
group = list(group)
daily_page_views = map(lambda r: int(r['daily_page_views']), group)
total_page_views = sum(daily_page_views)
popularity.append((group[0]['query'], total_page_views))
sorted_popularity = sorted(popularity, key=itemgetter(1), reverse=True)
languages, views = zip(*sorted_popularity)
result['languages'] = languages
result['views'] = views
return result
在這裡,我們首先按語言(詞典中的關鍵字“query”)來分組我們的資料,然後使用 python 的 groupby
函式,這是一個從 SQL 中借來的奇妙函式,從我們的資料列表中生成一組條目,每個條目都表示一些程式語言。然後,在第 14
行我們計算每一種語言的總頁面瀏覽量,然後新增 ('Language', rank)
形式的元組到 popularity
列表中。在迴圈之後,我們根據總瀏覽量對流行度資料進行排序,並將這些元組展開到兩個單獨的列表中,然後在 result
變數中返回它們。
最初的資料集有很大的偏差。我檢查了到底發生了什麼,並意識到如果我在 blogsearchengine.org 上查詢“C”,我就會得到很多無關的連結,其中包含了 “C” 的字母。因此,我必須將 C 排除在分析之外。這種情況幾乎不會在 “R” 和其他類似 C 的名稱中出現:“C++”、“C”。
因此,如果我們將 C 從考慮中移除並檢視其他語言,我們可以看到如下圖:
評估結論:Java 每天有超過 400 萬的瀏覽量,PHP 和 Go 有超過 200 萬,R 和 JavaScript 也突破了百萬大關。
每日網頁瀏覽量與谷歌排名
現在讓我們來看看每日訪問量和谷歌的部落格排名之間的聯絡。從邏輯上來說,不那麼受歡迎的部落格應該排名靠後,但這並沒那麼簡單,因為其他因素也會影響排名,例如,如果在人氣較低的部落格上的文章更新一些,那麼它很可能會首先出現。
資料準備工作以下列方式進行:
def get_languages_popularity(data):
query_sorted_data = sorted(data, key=itemgetter('query'))
result = {'languages': [], 'views': []}
popularity = []
for k, group in groupby(query_sorted_data, key=itemgetter('query')):
group = list(group)
daily_page_views = map(lambda r: int(r['daily_page_views']), group)
total_page_views = sum(daily_page_views)
popularity.append((group[0]['query'], total_page_views))
sorted_popularity = sorted(popularity, key=itemgetter(1), reverse=True)
languages, views = zip(*sorted_popularity)
result['languages'] = languages
result['views'] = views
return result
該函式接受爬取到的資料和需要考慮的語言列表。我們對這些資料以語言的流行程度進行排序。後來,在類似的語言分組迴圈中,我們構建了 (rank, views_number)
元組(從 1 開始的排名)被轉換為 2 個單獨的列表。然後將這一對列表寫入到生成的字典中。
前 8 位 GitHub 語言(除了 C)是如下這些:
評估結論:我們看到,所有圖的 PCC (皮爾遜相關係數)都遠離 1/-1,這表示每日瀏覽量與排名之間缺乏相關性。值得注意的是,在大多數圖表(8 箇中的 7 個)中,相關性是負的,這意味著排名的降低會導致瀏覽量的減少。
結論
因此,根據我們的分析,Java 是目前最流行的程式語言,其次是 PHP、Go、R 和 JavaScript。在日常瀏覽量和谷歌排名上,排名前 8 的語言都沒有很強的相關性,所以即使你剛剛開始寫部落格,你也可以在搜尋結果中獲得很高的評價。不過,成為熱門部落格究竟需要什麼,可以留待下次討論。
這些結果是相當有偏差的,如果沒有更多的分析,就不能過分的考慮這些結果。首先,在較長的一段時間內收集更多的流量資訊,然後分析每日瀏覽量和排名的平均值(中值)值是一個好主意。也許我以後還會再回來討論這個。
引用
- 抓取:
- 流量評估:
via: https://www.databrawl.com/2017/10/08/blog-analysis/
作者:Serge Mosin 譯者:Chao-zhi 校對:wxy
相關文章
- 2020年流行哪些程式語言?程式設計師的前景如何?程式設計師
- C語言I部落格作業03C語言
- C語言I部落格作業04C語言
- C語言I部落格作業05C語言
- C語言I部落格作業07C語言
- 全球流行程式語言資料表行程
- Python和其他流行的程式語言有什麼區別?Python
- Python是現在流行的程式語言嗎?前景怎麼樣?Python
- 多種語言後端流行的框架後端框架
- PYPL:2019年12月PYPL程式語言流行指數
- 如何使用Go語言寫出物件導向風格的程式碼Go物件
- 給部落格園的寄語
- 玩遍部落格網站,我整理了 Hexo 及其流行的風格主題網站Hexo
- 趨勢預測:2021年五大流行的程式語言
- 2018年最流行的十大程式語言,有你用的嗎?
- TIOBE 9 月程式語言:C++ 突起、Java 流行度下降C++Java
- 【Typora + 部落格園 】如何高效的在部落格園上編寫MD格式的部落格
- C 語言程式碼風格之 Linux 核心程式碼風格Linux
- 各種流行的程式設計風格程式設計
- 新版CSDN部落格如何新增別人的部落格連結
- 程式設計師如何搭建自己的個人部落格程式設計師
- 個人部落格程式
- 基於 go 語言開發部署的部落格 免費開源供參考Go
- 如何搭建部落格
- 為什麼中國開發不出流行的作業系統和程式語言作業系統
- Go語言的前景分析Go
- Go 語言程式碼風格規範-指南篇Go
- Go 語言程式碼風格規範-概述篇Go
- [python作業AI畢業設計部落格]FunctionalProgrammingForDummies-2019函數語言程式設計傻瓜書PythonAIFunction函數程式設計
- 飛雪無情的部落格Go語言、Android相關的十大熱門文章GoAndroid
- 如何轉載部落格,很不錯的
- 眾多程式語言如何抉擇
- 什麼是自然語言分析NLA,它是如何工作的?
- Bash 和 Python 程式語言優缺點分析Python
- Go 語言的詞法分析和語法分析(1)Go詞法分析語法分析
- 使用zig語言製作簡單部落格網站(六)文章詳情頁網站
- 第 09 篇:讓部落格支援 Markdown 語法和程式碼高亮
- IEEE Spectrum:2020年全球最流行語言是 PythonPython