豆瓣書籍數據爬取與分析


前言

17年底,買了清華大學出版社出版的《Hadoop權威指南》(第四版)學習,沒想到這本書質量之差,超越我的想象,然后上網一看,也是罵聲一片。從那個時候其就對出版社綜合實力很感興趣,想通過具體數據分析各個出版社的出版質量,另外借此也可以熟悉大數據生態和相關操作。

豆瓣上的書籍數據剛好可以滿足需求,所以有了思路:

1. 用python編寫爬蟲,爬取豆瓣上的書籍信息,並持久化到mysql數據庫;

2. 使用sqoop將mysql里的數據導入hive;

3. 通過hive進行離線分析。

 

一、爬蟲部分

這部分的代碼已經傳到個人的github:https://github.com/harrymore/DoubanBookSpider

1. 爬蟲思路及架構

通過觀察豆瓣網書籍的具體頁面,我們可以發現,具體書籍網址的組成形式為:

https://book.douban.com/subject/bookid/

其中bookid為具體的數字。第一種思路是設定一個比較大的數字,然后從1到這個數字的范圍之內去遍歷所有數字對應的網址,但是我們可以發現,這些書的id往往非常大,基本都是百萬級別的數字,一個個去撞庫非常不現實。

其實每本書都有很多標簽,每個標簽都匯集了同一類的所有書,要是可以獲取到所有標簽,然后根據這些標簽一個個去遍歷就可以獲得豆瓣上所有的書了,當然不同標簽之間肯定有重復的書,所以還要考慮去重的問題。

所以,這個爬蟲的思路主要是:

1) 爬取總標簽頁(https://book.douban.com/tag/?view=cloud)獲取所有標簽,並持久化;

2) 通過上一步獲取的標簽,組成標簽頁的網址,進入標簽頁獲得本頁的所有書籍鏈接,通過書籍鏈接獲取需要信息;

3) 對書籍信息進行標准化,持久化處理;

4) 爬完本標簽,切到下一個標簽,繼續爬,重復2,3步;

5) 應對網站反爬蟲機制;

6) 錯誤日志和程序崩潰處理。

編程語言選擇python,持久化工具選擇mysql數據庫。

 

2. 數據庫設計

1) 標簽信息

表名為tag_info,用來保存從豆瓣爬下來的標簽名字,另外,增加多兩個字段用來表示進度,一個是當前頁數,另一個是完成狀態。

2) 書籍信息:

表名為book_info,保存了每本書的基本信息,包括書名、作者、出版社、評分、評分人數等。為了去重,唯一id采用了豆瓣網中書籍的id。

 

3. 爬蟲框架及流程分析

在這個爬蟲中使用的模塊有 requests,BeautifulSoup,re,logging和MySQLdb,主要流程如下圖所示。

框架

1) 用requests模塊向豆瓣網發起GET請求,獲得網頁返回的信息;

2) 把上一步返回的信息用BeautifulSoup模塊進行分析,如果還需要進一步匹配過濾,傳給re模塊進一步加工,否則直接傳給MySQLdb模塊;

3) re模塊對BeautifulSoup傳過來的信息進行匹配處理,最后傳給MySQLdb;

4) 用MySQLdb連接mysql數據庫,將獲得的書籍信息持久化到mysql中;

5) 用logging模塊負責系統日志的輸出和維護。

 

4. 應對豆瓣的反爬蟲

實際上這次爬取數據,比計划多花了一倍時間,大部分時間在於應對豆瓣的反爬蟲機制。

剛開始requests去請求數據的時候,准備了若干個header,然后每次請求都換一個。沒過多久就開始返回403了,於是減低了爬取的頻率,還是繼續403。

查了半天資料,首次請求保存cookie,以后每次都修改cookiebid去請求,過一段時間還是被豆瓣檢測出來了,有的頁面直接返回空的或者定向到別的頁面。

最后想到了代理,寫了一個動態獲取免費代理並驗證的函數,不過免費的ip代理不僅慢而且不穩定,又不想買收費的代理服務。

后面查到了ADSL撥號服務器代理的相關文章,發現自己正是用ADSL上網,於是折騰了一番,寫了一個斷開路由器連接的函數,每當爬蟲被豆瓣封殺的時候,就斷開路由器連接重新獲取ip,由此解決了爬蟲正常運行的問題。當然,我這次爬取的數據量比較少,所以用這種方式還是能解決問題,如果是需要在短時間獲取大量數據的,還是需要用代理的方式。

流程

花了幾天時間,最后終於完成了所有標簽的爬取工作,爬到的數據去重后有6萬條左右。因為各個標簽之間肯定有重疊的部分,所以符合原來的預期。

 

二、使用sqoop將數據從mysql導入hive

1. 導入hive:

sqoop import --connect jdbc:mysql://localhost:3306/test --username root -P --split-by id --table book_info --target-dir /tmp/douban/book_info --hive-import --create-hive-table --hive-table douban.book_info --direct

 

2. 查看hive管理表結構

desc formatted book_info;
col_name        data_type       comment
# col_name              data_type               comment             
                 
id                      int                                         
book_name               string                                      
author                  string                                      
publisher               string                                      
translator              string                                      
publish_date            string                                      
page_num                int                                         
isbn                    string                                      
score                   double                                      
rating_num              int                                         
…(后面省略)                 

 

三、通過hive cli分析數據

1. 計算所有書籍的平均分

HiveQL語句:

SELECT AVG(score) AS avg_score FROM book_info WHERE score > 0 AND rating_num > 100;

為了准確,過濾掉沒有評分和評分人數不足的,結果:

OK
avg_score
8.057803307115979

平均分在8分左右,估計一般用戶都是看完一本覺得不錯的書才上豆瓣進行評分。

 

2. 計算清華大學出版社書籍的平均分

HiveQL語句:

SELECT AVG(score) AS avg_score FROM book_info WHERE publisher ='清華大學出版社' AND score > 0 AND rating_num > 100;

結果:

OK
avg_score
8.167039106145252

結果顯示清華大學出版社出版的平均分比總體的稍高,但是也沒有很突出。

 

3. 計算平均分排名前十的出版社

HiveQL語句:

SELECT publisher, AVG(score) as avg_score, COUNT(id) AS book_num
FROM book_info
WHERE score > 0 AND rating_num > 100
GROUP BY publisher
HAVING COUNT(id) > 10
ORDER BY avg_score
DESC
LIMIT 10;

結果:

publisher       avg_score       book_num
茜新社             9.157894736842104       19
山西古籍出版社     9.027272727272727       11
太田出版           8.933333333333334       15
浙江人民美術出版社 8.930769230769231       13
東立出版社有限公司 8.910526315789474       19
少年兒童出版社     8.898484848484848       66
上海辭書出版社     8.887500000000001       16
上海科學技術出版社 8.86875 16
白泉社             8.857692307692309       26
岳麓書社           8.845833333333331       24

可以看出排名前十的出版社平均分都在8.8以上,最高的平均分達9.16分。

 

4. 計算清華大學出版社的排名

HiveQL語句:

FROM (
SELECT publisher, count(id) as book_num, AVG(score) as avg_score, row_number() over(ORDER BY avg_score DESC) as rank_num
FROM book_info 
WHERE score > 0 AND rating_num > 100
GROUP BY publisher
HAVING count(id) > 10
LIMIT 200) t1
SELECT t1.*
WHERE t1.publisher = '清華大學出版社';

結果:

t1.publisher    t1.book_num     t1.avg_score    t1.rank_num
清華大學出版社  179     8.167039106145252       146

數據顯示清華大學出版社的排名100名之內都排不進,而且如果把每個出版社出版書籍數量放寬一點來處理的話,結果會更難看一點。

 

四、小結

實際上只要找到合適的數據源,就能夠通過這些數據挖掘出自己需要的東西。從數據采集到最后產出分析結果,整個過程相對來說還比較粗糙,sqoop和hive部分由於數據量不大,只是作為學習目的來檢索,暫時未涉及到分區和分桶的操作,因為數據量小,查詢也沒作並行優化,等后面有時間再進行深入。

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM