一個人人網python爬蟲

發表於2016-04-11

Background

不知道現在還有多少人在使用人人網,但是在我剛上大學的時候人人網還有開心網還是很火的,然而它們都相繼死去了。倒是高中時喜歡玩的QQ空間依舊風生水起。

但是畢竟在人人網上留下了很多東西,將來一不小心人人閘道器掉了(這種可能我感覺越來越大,畢竟資本市場不會說謊),這些東西丟掉豈不是很可惜?

每天發生的各種瑣事,你此時棄之如敝屐,珍之如瑰寶,在不久的將來會化作一串串珍珠,讓人憑弔……然而珍珠也會蒙塵,所以還是儘可能地保護吧!

最終程式碼

RenRenDownload

遇到的一些問題

1.登入

用python實現模擬登入人人網

2.驗證碼

在登入那篇部落格中已提到驗證碼的問題,實際當中應該是登入時重複多次輸錯密碼導致的。

之後我又發現,在之後爬去好友的個人資訊時,人人網對瀏覽數進行了限制,當對好友的個人頁面瀏覽量累計超過100時,人人網會進行一次驗證碼識別。

解決思路都是將圖片下載下來,將識別後的字串返回。關於如何確保返回的驗證碼不是重新整理後的新驗證碼,詳見上述部落格的最後幾段。

3.Python中的中文,Unicode

如果涉及到中文,Python處理字元時經常會報錯。
主要學習參考以下幾篇博文:

  1. 字元編碼筆記:ASCII,Unicode和UTF-8
  2. PYTHON-進階-編碼處理小結
  3. 也談 Python 的中文編碼處理

首先是程式碼中的編碼問題,詳見第一篇。
剛開始的英文只需要256個字元編碼就可以解決問題,即ASCII,可以說是計算機中最基礎的編碼了吧,記得大學第一門計算機專業課就對它進行了講解。
然而除了英文之外還有許多其他字元需要進行編碼工作,例如中文。但是沒有一種編碼方式將這些ASCII編碼無法涵蓋的字元進行統一規則,知道出現了Unicode。如名字一樣,每個字元對應的編碼都是獨一無二的。
但是Unicode只是一個很大的集合,只規定了符號的二進位制程式碼,而沒有規定在計算機中應該如何儲存。
後來,隨著網際網路的發展,需要一種統一的編碼方式進行通訊,UTF-8就是一種Unicode的編碼方式,並且是應用最廣的。
以上就是三者的關係。

然後是Python中的編碼問題。
我們經常遇到兩種型別的字元,一種是str,一種是Unicode。
Python認為Unicode才應該是最基礎的編碼。所以str變Unicode是str.decode(‘str的編碼方式’),而Unicode變str是Unicode.encode(‘想要變成的編碼方式’)。
為了防止意外,理想的情況是,從外界輸入進來的字元,統一decode成Unicode,在Python程式碼中統一使用Unicode,在輸出至外界時,再根據所需encode成對應的字元。
另外,在Python程式碼開頭,統一宣告# –– coding: utf-8 –表示該程式碼內部的str編碼方式均為utf-8,方便之後進行轉換(雖然python本身進行預設轉換時,並不會參考該設定)。

如果出錯,一般會有兩種報錯:

有時候是我們寫程式碼時不小心掉入陷阱,有時候則是python使用預設編碼規則轉換時出錯(例如str和Unicode型別進行拼接,或者進行輸入輸出)。

通過以下程式碼可以得知當前python使用的編碼規則:

結果是ascii
我們可以將它進行強制設定(不推薦):

這樣的話可以避免一些錯誤。

不同編碼轉換時,推薦先decode成Unicode,再encode成最終編碼。

同樣的道理,如果在控制檯上發現讀取檔案是亂碼,可檢視下是否是編碼方式錯誤,在資料庫中,也同樣是道理。

有個庫可以進行編碼識別:chardet。

4.json

爬取過程中,發現有資料是直接返回的json,有資料是html中的一段但是也是json格式。
一般通過如下進行獲取,s表示字串:
dictinfo = json.loads(content)
但是python的json模組要求key值和value值都用雙引號,而人人網返回的資料中,key和value中單引號和雙引號都有使用,需要更改。然而有的單引號需要變成雙引號,有的不需要(只出現了一次:某個value是一段html,其中有一個連結包含http:,如果更改為雙引號,則此冒號會造成誤解),所以需要挨個字元進行判斷。
匯入成功後,就可以使用如下方式進行讀取:
dictlinfo[key值]

5.MySQL

簡單教程:
MySQL 教程
python操作mysql資料庫

使用sql輸出table所有項:

匯出表作為原始資料:
在命令列輸入

其中directory即為匯出到的目錄

匯出sql格式的資料:
在命令列輸入

如果要匯出整個database,則去掉上面命令中的table_name。
如果要匯出所有database(==備份資料庫),則是:

關於在Mysql中使用中文,建立資料庫的時候預設的編碼方式是latin1,而不是utf-8.
可以通過如下命令來檢視對應資料庫、表的編碼方式:

可以通過如下命令來檢視建立時使用的預設編碼方式:
show variables like ‘%char%’
如果需要更改,可以執行:

只不過這些設定都是臨時的,下次啟動後還會還原成原先的情況。

那麼要在Mysql中使用中文,首先建立時要設定好編碼方式。
資料庫預設是latin1:

還需要設定collation即比對方法,合起來如下:

同時python連線時也要設定為utf8,可以通過在MySQLdb.connect(**arg)的入參中設定’charset’:’utf8’。
另一種方法是連線建立後,執行connect.set_character_set(‘utf8’)。
或者是執行SET NAMES utf8。

參考:
讓MySQL支援中文
mysql 中 character set 與 collation 的點滴理解
mysql編碼詳解


最後再來上一次程式碼:RenRenDownload

相關文章