python微博爬蟲編寫

  因爲最近要做一個爬到微博中所有用戶發表的微博以及所有用戶的點贊、評論以及轉發操作,因此學習了一下如何使用python編寫微博的爬蟲。爲了防止後續再次用到,再加上之前在一個奇怪的地方定下了新年要寫微博的新年目標,因此,特地記錄了下來。
  首先聲明一下環境,電腦裝的windows10系統,準備使用python2.7+scrapy這兩樣東西拼起來搞一個微博的爬蟲。

環境的配置

python的安裝

  首先是python的下載和安裝,考慮到網絡上資料有限,個人比較慫的選擇了較爲古老的python2.7,而不是較新的python3。下載地址:python2.7。安裝起來比較簡單,一路無腦next即可。
  之後需要稍微對環境變量進行一下配置,從而方便後續使用。具體方法:
  添加了一個 PYTHON_HOME的系統變量,值是C:\Program Files (x86)\python27;C:\Program Files (x86)\python27\Scripts,再之後修改PATH這一系統變量,把剛剛的%PYTHON_HOME%這個變量加到最後。
  現在,直接在cmd裏面輸入python就有了如下輸出:
  python安裝成功效果
  至此,python27安裝成功。

IDE的選擇

  沒有IDE我爲什麼要用windows。python自帶的ide實在是不好用,我隨便選擇了一個ide使用:Wing IDE。下載和破解鏈接這裏就不貼了,現用現查。可喜可賀的是Wing IDE居然支持vim的快捷鍵,然而並不支持自定義的vimrc。事實證明,即使可以也儘量不要修改默認的快捷鍵,不然都是淚啊。現在一般的vim用起來都難受了。

scrapy的安裝

  說道爬蟲,大部分人都會用到python。對於裏面的道理大體就是因爲可用的庫比較多。相對於python自帶的urllib和urllib2的庫,第三方框架scrapy用起來更爲的強大和方便。
  安裝scrapy相對於安裝python2.7要曲折的多。首先是直接安裝。打開cmd,之後使用如下命令(如果你配好了環境變量的話),如果你幸運地話,就有一定可能可以直接安裝成功。

pip.exe install scrapy

  成功後的結果是有一個很明顯的成功信息。忘了截圖了。
  然而,我並不是一個十分幸運地人。整個安裝過程中,我主要遇到了三個問題,記錄下來方便後續看。對不起觀衆的是由於錯誤已經被解決,所以錯誤消息已經殘缺不全了。

權限不足

  這個最爲簡單,就是說權限不足不可以在c盤中的一個目錄裏面創建一個文件,從而導致安裝失敗。解決的也很簡單,直接使用管理員權限運行cmd即可。

沒有vs的庫

  這個問題已經比較噁心了。問題如下:

Microsoft Visual C++ 9.0 is required  (Unable to find vcvarsall.bat)

  經過一番搜索發現瞭解決,因爲python2.7所帶的pip是和vs2010一個年代的東西,因此用的是vc++9.0的東西們。解決方法有兩個,一個是升級pip,我慫,沒敢搞。
  另一個方法就是我用的。因爲我的機子上已經裝了vs2014的庫,所以只需要將vc++9指向實際的vc++14的位置即可。方法如下,修改系統變量,添加如下一項。
  系統變量
  當然前提是你的系統變量裏面有那個14的東西。方便複製我打印一遍VS90COMNTOOLS%VS140COMNTOOLS%
  如果還不行可以參考這個鏈接嘗試照着下載一下:別人家處理這個問題的博客

沒有xmllib

問題如下:

 c:\users\f\appdata\local\temp\xmlXPathInitqjzysz.c(1) : fatal error C1083: Cannot open include file: 'libxml/xpath.h': No such file or directory
  *********************************************************************************
  Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
  *********************************************************************************
  error: command 'C:\\Users\\f\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\cl.exe' failed with exit status 2

  順便一提,當時我因爲vs的問題棄療在Ubuntu上頭捯飭python的時候就是因爲碰到了這個問題所以又回到了windows平臺下。
  解決方法其實更加簡單,查詢了stackoverflow,如下操作即可:

easy_install lxml

  至此,scrapy安裝成功,在cmd命令行下輸入scrapy,可以看到類似如下信息。
  可喜可賀可喜可賀

其他問題

  後來我在看scrapy的文檔的時候發現我還是naive了,其實上面還沒有成功,也不是很好複製。正確的安裝方法應該參考如下鏈接,ssl我之前不知什麼時候安裝過,而沒有安裝pywin32的後果也在後續運行scrapy shell的時候顯示了出來。這件事情啓示我們,先看文檔再動手。官方文檔中的安裝指南看這裏

迭代一,保存每個用戶的首頁

  爲了熟悉一下環境,做了一個簡單的迭代一,主要目的就是爬取每一個用戶的首頁到預期用戶id對應的文件中。

入門文檔

  scrapy的官網爲我們提供了比較詳細的文檔,特別可喜可賀的是居然還有中文文檔,簡直省勁。在開始寫之前,建議先花費一兩個小時吧入門文檔看一下,瞭解一下最基礎的架構,什麼事spider,什麼事item,什麼事pipeline,如何創建項目等。具體的見一下兩個鏈接:初窺入門教程

選擇爬取網頁:wap>電腦版

  這是我在某一個大腿的知乎上面看到的一個重要的經驗,要寫一個網站的爬蟲時,優先嚐試wap版本該網站,這個版本一般css少,網頁簡單,表單清晰,沒有ajax,總之特別好。比如就微博而言,衆所周知的weibo.com的網頁複雜無比,還有花式的js腳本。而如果選擇了wap版本的weibo.cn,審查源代碼可以看到,非常的簡單明瞭。
  其實原文上面說的是wap>移動版>電腦版,但是對於wap和移動版之間的區別我還是不是很懂,暫時的理解是wap版相當於好多年前的2G版應用,移動版相當於3G版應用,自然前者要好很多。如有不對,後續再修改

對微博url的簡要分析

  在微博中,每個用戶都有一個唯一的uid,作爲該用戶的標示。當你訪問某一用戶首頁的時候,地址的url通常如下:http://weibo.cn/u/***,這裏的*就是該用戶的uid,有十個數字組成。打個比方:http://weibo.cn/u/1421647581(笛子大大是個好大大)。
  因此,這次迭代的任務比較簡單,主要是熟悉環境,爬取形如weibo.cn/u/%uid%的網頁,並保存到uid的同名文件中即可。

編寫spider

  因爲這只是測試一下scrapy的簡要操作,因此我們就不使用item和pipeline了,只是單純的編寫一個簡單的spider來進行爬取。

spider的大致流程

  對於一個spider,其操作流程大致如下,首先進行初始化,之後對於其成員變量start_urls中的每一個字符串,調用make_request_from_url方法,將其變成一個requesst,並且開始從這個request進行爬取。
  當這個request的網頁數據下載完成後,會調用這個request所對應的回調函數對爬取結果進行處理。每一個回調函數都可以返回兩種值:
  一種是request的list,這種情況下,scrapy會自動把這些request添加到待爬取的request中,繼續進行爬取。默認情況下,似乎是一種類似於bfs的添加方式,也可以通過調整設置調節爲類似dfs的方式。(待驗證
  另一種是item的list。item的詳細定義見官方文檔,若返回item的list,則會將每一個item都是用pipeline存儲到合適的位置。

初始化

  知道spider的大致流程後就可以開始編寫了。首先是一些必要的初始化操作。代碼如下:

    uidFileName = "D:\\uid.txt"
    name = 'weiboSpider'
    def __init__(self, category=None, *args, **kwargs):
        super(WeiboSpider, self).__init__(*args, **kwargs)
        self.header = {
            'Connection' : 'keep-alive',
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36',
            'Accept-Encoding' : 'gzip, deflate, sdch',
            'Accept-Language' : 'zh-CN,zh;q=0.8',
        }
        try:
            dataFile = open(self.uidFileName, "r")            
        except:
            sys.stderr.write("please check the uid file exists!")
            exit()
        try:
            self.cookie = eval(open("D:\\cookie.txt", "r").readline())
        except:
            sys.stderr.write("please check the uid file exists!")
            exit()
        self.start_urls = ['http://weibo.cn/u/3433941822']
        for line in dataFile:
            lineUids = eval(line.split("\t")[1]).keys()
            for lineUid in lineUids:
                self.start_urls.append("http://weibo.cn/u/"+lineUid)                

  其中,最重要的是兩個部分的初始化,一個是name,這是scrapy框架所要求的爲每一個spider都要有一個唯一的name。這樣,後續的命令行命令中纔可以使用scrapy crawl %name%來調用相應的spider進行爬取;第二個是start_urls,及爬蟲的入口地址,就是最初需要開始爬取的網址們。
  這裏我已經實現從一個奇妙的地方獲得了許許多多的用戶的uid,並保存到了文件中,直接從文件中讀取即可。(關於遍歷文件那個快這一爭端性問題,請見一個不是特別底層的討論
  至於cookie和header,主要是後續用來模擬登陸和瀏覽器訪問使用的,請見下一節。

設置header和cookie,模擬登陸

  對於weibo.cn這個wap頁面來說,不登錄是不會讓你訪問任何一個人的主頁的。因此,我們需要首先模擬登陸。這一步我偷了個懶,直接使用瀏覽器進行登錄,之後使用fiddle進行抓包,再之後把這個包中的header和cookie拷貝了出來,在後續直接強行設死,從而方便裝作瀏覽器的樣子進行登錄。寫死header和cookie的代碼見init(這裏還有一點問題,我是用相對路徑跑不起來,不是很懂),使用時候的代碼如下:

    def make_requests_from_url(self, url):
        return Request(url, headers=self.header, cookies=self.cookie)

  這裏就是用了我們之前說的make_requests_from_url,設置了一下header和cookie。(這裏的cookie不算在header裏面,我之前urllib用慣了在這裏坑了好久。)這裏還有一個小問題,如果cookie改變了會如何。文檔上面說scrapy會根據setcookie自動設置,但是我這裏make_request_from_url直接寫死了會不會死

parse

  最後是一個簡單版本的parse,這裏實在太簡單了,就是直接把獲得的response保存到相應的文件中即可。代碼如下:

    def parse(self, response):    
        filename = response.url.split("/")[-1]
        print response.url
        open("D:\\scrapytmp"+filename+".html", "wb").write(response.body)

  之後,在項目路徑下(及和scrapy.cfg這一文件在同一層目錄下的地方打開cmd,運行scrapy crawl weiboSpider,即可看到我們的爬蟲正確的運行了起來。打開d盤,就可以看到新保存的文件了。

未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章