用Python爬取WordPress官網所有外掛

xodyhu發表於2019-03-07
轉自丘壑部落格 轉載註明出處

前言

只要是用WordPress的人或多或少都會裝幾個外掛,可以用來豐富擴充套件WordPress的各種功能。圍繞WordPress平臺的外掛和主題已經建立了一個獨特的經濟生態圈和開發者社群,養活了眾多的WordPress相關的開發公司和開發者。各種強大的WordPress外掛也層出不窮,有的甚至可以做出功能完善的網站,比如招聘網站、分類資訊網站、電商網站、點評網站、培訓網站等等,令我讚歎不已。

最近一直沉迷於研究 WordPress,彷彿事隔多年與初戀情人再續前緣一般陷入熱戀。這幾天突發奇想把WordPress上這麼多眼花繚亂的外掛都爬下來,看看能不能分析出一點有意思的東西來。

總體思路

官網外掛的頁面 wordpress.org/plugins/ 上列出了一共有 54,520 個外掛。記得以前在官網上可以按各種分類瀏覽的,現在只有推薦的外掛、收藏的外掛、流行的外掛幾大類顯示出來,其他的好像只能靠人肉搜尋了。其實挺不方便的。

那麼首先第一步我們要知道取哪裡可以找到所有的WordPress外掛列表,搜了一圈發現WordPress的svn上有這個完整的列表, plugins.svn.wordpress.org/ (這個網頁比較大,5M多,慎點),比官網上的還要齊全,一共7萬多個。有了完整列表就好辦了。

接下來就是要獲取的是外掛的各種資訊,比如作者、下載量、評分等等。這個可以去哪裡獲取呢?當然最傻的辦法就是根據上面列表中的外掛地址,把每個外掛的網頁down下來再提取,這也就是爬蟲乾的事。不過 WordPress.org 網站自身的 WordPress.org API 已經給開發者提供了非常方便強大的介面,可以獲取到幾乎所有 wordprss.org 上的主題、外掛、新聞等相關的資訊,也支援各種引數和查詢。注意,這個和WordPress的REST API是兩回事。基本上你可以理解成 Apple.com 的 API 和 iOS 的 API 之間的區別(雖然apple.com並沒有什麼API。。。)

比如本次需要外掛的一些資料,那就可以使用關於外掛描述的 API, https://api.wordpress.org/plugins/info/1.0/{slug}.json,slug也就是每個外掛唯一的地址,這個在剛才svn上已經可以獲取到了。用這個 API 可以返回關於外掛的 json 格式的各種詳細資訊,很全面,如下:

kvg8vF.png

有了列表,有了返回格式,接下來就是要把這些資訊給扒下來,其實就是重複遍歷一遍就可以了,要麼用著名 Python 的 Requests庫 迴圈一圈,要麼使用 Python 的爬蟲框架 Scrapy, 都是可以的 。在儲存爬取資料儲存方面,本來打算用scrapy並且存入 mongodb 的,但是遇到的一個坑是API返回的json物件裡version有的key是帶小數點的,比如”0.1″這種是無法直接存入mongodb的,會報錯說key不能包含點.

"versions": {
    "0.1": "https://downloads.wordpress.org/plugin/0-errors.0.1.zip",
    "0.2": "https://downloads.wordpress.org/plugin/0-errors.0.2.zip",
    "trunk": "https://downloads.wordpress.org/plugin/0-errors.zip"
  },
複製程式碼

InvalidDocument: key must not contain ‘.’

不用就不用唄。。。改key才蛋疼了。所以這可以祭出另外一個厲害的python庫 jsonline了, 它可以以jsonl檔案的形式一行儲存一條json,讀寫速度也很快。最後爬完所有資料的這個檔案有341M之大。。。

最後,有了資料就可以做一些有意思的資料分析了,這一步主要會用到的就是一些常見的 Python 的資料分析工具和圖表工具,pandas、numpy、seaborn等。根據上面的返回資訊可以看出,能夠分析的維度也是很多的,比如哪些作者開發的外掛最多、哪些外掛的下載量最多、哪些類別的外掛最多、哪些國家的開發者最多、每年的外掛增長量等等,甚至更進一步可以把所有外掛的zip檔案下載下來用AI做一些深入的程式碼分析等等,想想還是挺有意思的,本文的目標也就是提供一種思路和方法,希望能拋磚引玉。

下面進開始進入程式碼的世界吧

爬取資料

準備工作

要爬資料一般第一步是要確認爬蟲的入口網頁,也就是從哪裡開始爬,沿著入口網頁找到下一個URL,找-爬-找,不斷迴圈重複直到結束。一般來說入口網頁的分析都可以在scrapy內部進行處理,如果事先就已經可以明確知道所有要請求的網頁地址,那麼也可以直接把url列表扔進scrpay裡,讓它順著列表一直爬爬爬就行了。

本次為了說的清晰一點,爬蟲部分不用再次解釋,所以分步進行,先把要爬的所有url準備好等下可以直接使用。之前說過了,WordPress所有的外掛名稱列表在這裡可以找到 http://plugins.svn.wordpress.org/ ,這網頁是一個非常簡單的靜態網頁,就是一個巨大的ul列表,每一個li就是一個外掛名字:

plugins.svn.wordpress.org的網頁原始碼

這裡的href就是外掛的slug,是wordpress.org用來確定外掛的唯一標示。解析這種html對Python來說簡直是小菜一碟,比如最常用的 BeautifulSoup 或者 lxmp,這次決定嘗試一個比較新的庫,Requests-HTML: HTML Parsing for Humans ,這也是開發出Requests庫的大神kennethreitz的又一力作,用於解析 HTML 文件的簡直不要太爽了。

slug得到後,按照API的url格式地址組合起來,全部寫入一個檔案中就可以了。

python庫requests_html的用法

作為對比,可以看下用 BeautifulSoup 的方法:

python庫BeautifulSoup的用法

就這麼一個簡單對比還是比較明顯的,簡單明瞭。最終,這一步的輸出結果就是這個all_plugins_urls.txt檔案了,總共有79223個外掛

有了這個列表,其實下面的Scrapy步驟其實完全可以不用,直接拿wget都可以全部簡單粗暴的懟下來7萬個json檔案:

wget -i all_plugins_urls.txt複製程式碼

或者用requests簡單的遍歷請求一下就完事了,就可以得到所有外掛的資料,進而可以直接進入資料分析階段了。為了作為演示吧,也算作是一個簡單的scrapy的介紹,對於沒有接觸過scrapy的朋友來說,可以是一個很初步的入門介紹。

安裝 scrapy

這一步最簡單的方式就是pip安裝

pip install Scrapy
scarpy -V # 驗證一下複製程式碼

新建專案 (Project):新建一個新的爬蟲專案

scrapy 提供了完善的命令工具可以方便的進行各種爬蟲相關的操作。一般來說,使用 scrapy 的第一件事就是建立你的Scrapy專案。我的習慣是首先新建一個資料夾(用要爬的網站來命名,這樣可以方便的區分不同網站的爬蟲專案)作為總的工作區, 然後進入這個資料夾裡新建一個 scrapy 的專案,專案的名字叫做 scrap_wp_plugins,可以改成你想要的名字

mkdir ~/workplace/wordpress.org-spider
cd ~/workplace/wordpress.org-spider
scrapy startproject  scrap_wp_plugins複製程式碼

這樣就會自動建立好類似如下的檔案結構:

├── scrap_wp_plugins
│   ├── __init__.py
│   ├── __pycache__
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       ├── __init__.py
│       └── __pycache__
└── scrapy.cfg

4 directories, 7 files
複製程式碼

對我們這個需求來說,除了settings.py需要做一點點修改,其餘檔案都先不用管它,在這個簡單的不能再簡單的專案裡都用不到。

目前只是一個空架子,啥也幹不了,因為還沒有爬蟲檔案,你可以完全純手寫,也可以用模板來生成一個。我們就用scrapy的命令列自動生成一個爬蟲,語法格式是這樣:

Syntax: scrapy genspider [-t template] <name> <domain>

template 是要使用的爬蟲的模板,預設的就是用最基本的一個。

name 就是爬蟲的名字,這個可以隨便取,等下要開始爬的時候會用到這個名字。好比給你的小蜘蛛取名叫“春十三”,那麼在召喚它的時候你就可以大喊一聲:“上吧!我的春十三!”

domain 是爬蟲執行時允許的域名,好比說:“上吧!我的春十三!只沿著這條路線上!”

所以執行如下命令即可:

cd scrap_wp_plugins
scrapy genspider plugins_spider wordpress.org複製程式碼

這樣就會在spiders資料夾下生出一個叫plugins_spider.py的爬蟲檔案,也就是在這裡面可以填充一些爬取邏輯和內容解析。

製作爬蟲(Spider):製作爬蟲開始爬取網頁

首先我們開啟scrap_wp_plugins/plugins_spider.py看下里面的內容:

Created spider ‘plugins_spider’ using template ‘basic’ in module: scrap_wp_plugins.spiders.plugins_spider

可以看出這就是一個最簡單scrapy的Spider的類而已,自動填入了上一步用來建立爬蟲時的一些引數。

name:爬蟲的識別名,它必須是唯一的,在不同的爬蟲中你必須定義不同的名字,就是上一步的命令列裡寫的plugins_spider.

start_urls:爬蟲開始爬的一個URL列表。爬蟲從這裡開始抓取資料,所以,第一次下載的資料將會從這些URLS開始。其他URL將會從這些起始URL中繼承性生成。具體來說,在準備工作那一部分,我們已經得到了一個urls的列表檔案all_plugins_urls.txt,現在只需要把這個檔案讀取進來就好了。

parse():爬蟲的方法,呼叫時候傳入從每一個URL傳回的Response物件作為引數,response將會是parse方法的唯一的一個引數,
這個方法負責解析返回的資料、匹配抓取的資料(解析為item)並跟蹤更多的URL。在本專案中,因為返回的是json,不需要解析任何html,這裡為了省事我就直接把json整個儲存起來已備後面資料分析的時候再選擇需要的欄位,當然你也可以根據需要選擇過濾掉不需要的json欄位。

所以,我們的第一個爬蟲就呼之欲出了!請看程式碼,麻雀雖小五臟俱全

a simple spider will crawl all plugins from wordpress.org

執行爬蟲

改完上面的爬蟲程式碼,現在就可以讓爬蟲跑起來了,“上吧!比卡丘!”

scrapy crawl plugins_spider複製程式碼

哦嚯。。。

kv7Xgs.png
Forbidden by robots.txt

意外發生了。。。啥也沒爬下來??

Don’t Panic
!別慌,仔細看下報錯資訊,原來是 api.wordpress.org/robots.txt 規定了不允許爬蟲,而scrapy預設設定裡是遵守robot協議的,所以簡單繞過就行了,開啟 setttings.py, 找到下面這行,把True改為False,意思是:“愛咋咋地,老子不屌你的robots.txt ”

# Obey robots.txt rules
ROBOTSTXT_OBEY = True複製程式碼

再次執行現在就可以愉快的爬取了。還有一點溫馨提示,如果爬取網址數量比較多,不想中途因為斷網或者其他什麼鬼知道的意外中斷,導致下次又要重新來過,可以加上scrapy的執行日誌來儲存爬蟲狀態,下次就會從中斷處開始繼續爬取

scrapy crawl plugins_spider -s JOBDIR=spiderlog   --logfile  log.out  &複製程式碼

這樣就可以安心的去睡個覺,一早起來就能看到熱呼呼新鮮出路的WordPress所有的外掛資訊了。

未完待續

本想放在一篇寫的,沒想到光爬資訊這點東西寫了這麼多寫到這麼晚。。。。可能東拉西扯廢話太多了,下一篇繼續再寫關於資料分析的科普文吧。

bestscreenshot.com/scrap-all-p…


相關文章