基于PySpider的weibo.cn爬蟲(chóng)

作為科研狗袜刷,新浪微博一生黑。一開(kāi)始打算花錢(qián)買(mǎi)他們的商業(yè)API愕宋,結(jié)果跟我說(shuō)不跟科研機(jī)構(gòu)合作玻靡,我也是日了狗了。后來(lái)費(fèi)盡千辛萬(wàn)苦寫(xiě)了個(gè)爬蟲(chóng)中贝,差點(diǎn)沒(méi)把我小號(hào)封了手動(dòng)再見(jiàn).gif本來(lái)寫(xiě)字的陣地主要在lofter囤捻,結(jié)果lofter這坑貨不支持代碼高亮,讓我這個(gè)碼農(nóng)如何自處邻寿?好了蝎土,閑話少敘已經(jīng)敘了不少,把我這三天的奮斗結(jié)果稍稍記錄一下绣否。

一些學(xué)習(xí)資料

  1. Fiddler簡(jiǎn)易使用教程 抓cookies用(必看)
  2. PySpider簡(jiǎn)易教程 整個(gè)爬蟲(chóng)用到的框架(必看)
  3. HTTP Header入門(mén)詳解 在模擬登錄過(guò)程中要涉及到http頭的設(shè)置誊涯,需要了解基本信息
  4. 全程模擬新浪微博登錄2015 這個(gè)分析了新浪微博網(wǎng)頁(yè)版現(xiàn)在還在用的登錄過(guò)程,其中使用到的最新腳本ssologin.js版本號(hào)1.4.18蒜撮。不過(guò)本文主要是基于wap版的爬蟲(chóng)暴构,這個(gè)沒(méi)必要看,如果想進(jìn)一步爬取網(wǎng)頁(yè)版的微博可以參考學(xué)習(xí)淀弹。
  5. Sina微博爬取@pyspider 這篇文章通過(guò)用戶名和密碼獲取wap版微博的cookies后再進(jìn)行后續(xù)操作丹壕,也可參考。
  6. PyQuery文檔 && CSS選擇器&&Python正則表達(dá)式re package文檔
    Python頁(yè)面爬下來(lái)以后用于操作頁(yè)面元素獲取需要的內(nèi)容(必看)

獲取cookies用于模擬登陸

參考學(xué)習(xí)資料1里面設(shè)置好fiddler薇溃,然后打開(kāi)http://weibo.cn/ 沒(méi)登陸的話登陸菌赖。在登錄的狀態(tài)下打開(kāi)你要進(jìn)行爬取的頁(yè)面,觀察fiddler里抓到的包沐序,得到需要的cookies信息

獲取cookies

對(duì)應(yīng)設(shè)置好PySpider里的crawl_config琉用,需要注意的是cookiesheaders堕绩,考慮到我的代碼邏輯我把這兩個(gè)都放在crawl_config里而不是具體的爬取函數(shù)里。關(guān)于頭的設(shè)置也可以參考fiddler里Headers一欄邑时,完整代碼貼在最后可以參考我的設(shè)置奴紧。

爬蟲(chóng)邏輯

我的需求是對(duì)于指定的用戶,給出用戶主頁(yè)(形如http://weibo.cn/kaikai0818http://weibo.cn/u/1788136742)晶丘,爬取TA全部的微博及相關(guān)信息(如發(fā)布時(shí)間黍氮、轉(zhuǎn)發(fā)數(shù)等)。

入口函數(shù)on_start沒(méi)什么可說(shuō)的浅浮,因?yàn)樵O(shè)置了全局的headers和cookies這邊在self.crawl的時(shí)候就不需要再發(fā)送了沫浆,如果沒(méi)設(shè)置成全局的,必須在這邊設(shè)置并發(fā)送滚秩。

index_page函數(shù)主要用來(lái)計(jì)算一共有多少頁(yè)需要爬取专执,頁(yè)面有一個(gè)類型為hidden<input>元素記錄了一共有多少頁(yè),然后一個(gè)for得到所有需要爬取的頁(yè)面地址郁油。

list_single_page用于處理每一頁(yè)微博的內(nèi)容本股,一頁(yè)有十條,主要就是操作頁(yè)面獲取單條微博的地址(因?yàn)楹罄m(xù)需求可能需要爬取每一條微博的轉(zhuǎn)發(fā)和評(píng)論內(nèi)容)桐腌。這邊有個(gè)trick拄显,和web版微博不同的是,wap版單條微博并沒(méi)有一個(gè)所謂的地址哩掺,只有一個(gè)轉(zhuǎn)發(fā)或者評(píng)論的地址凿叠,代碼里用了轉(zhuǎn)發(fā)的地址涩笤。值得注意的是我自己測(cè)試這個(gè)爬蟲(chóng)的時(shí)候爬了1500條微博左右的時(shí)候賬號(hào)被凍結(jié)了嚼吞,建議在dashboard調(diào)一下rate、burst值蹬碧。不過(guò)后來(lái)登錄后激活了一下賬號(hào)又能用了舱禽,還沒(méi)測(cè)試過(guò)多少值可以避免被凍,因?yàn)椴磺宄吕藘鼋Y(jié)的機(jī)制恩沽,我的小號(hào)還要用來(lái)花癡的誊稚,不敢瞎搞了(:з」∠)

detail_page用來(lái)處理單條微博,然后就是css選擇器+正則的應(yīng)用了哇罗心,沒(méi)什么可說(shuō)的里伯,就是找規(guī)律,目前測(cè)試過(guò)了沒(méi)啥問(wèn)題渤闷,不過(guò)爬下來(lái)的1500多條也沒(méi)認(rèn)真檢查過(guò)疾瓮,大家自己再看看了哇。

一個(gè)能跑的代碼如下:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2016-03-07 13:26:00
# Project: user_timeline

import re
import time
from pyquery import PyQuery
from pyspider.libs.base_handler import *

class Handler(BaseHandler):
    user_url = "http://weibo.cn/kaikai0818"
    
    crawl_config = {
        'itag': 'v1',

        'headers': {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0',
            "Host": "weibo.cn",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh-TW;q=0.8,zh-HK;q=0.6,en-US;q=0.4,en;q=0.2",
            "Accept-Encoding": "gzip, deflate",
            "DNT": "1",
            "Connection": "keep-alive"
        },

        'cookies': {
            "_T_WM":"I?kkw(ˉ﹃ˉ)",
            "SUB":"I?kkw(ˉ﹃ˉ)",
            "gsid_CTandWM":"I?kkw(ˉ﹃ˉ)",
            "_T_WL":"1",
            "_WEIBO_UID":"I?kkw(ˉ﹃ˉ)" 
        }
    }
    

    @every(minutes=24 * 60)
    def on_start(self):        
        self.crawl(Handler.user_url, callback=self.index_page,method="GET")   
    

    @config(age=1 * 24 * 60 * 60)        
    def index_page(self, response):
        #計(jì)算該用戶的微博共有幾頁(yè)
        pages = response.doc("[type=hidden]").attr["value"]            
        for i in range(1,int(pages)+1):
            self.crawl(Handler.user_url+"?page="+str(i), callback=self.list_single_page,method="GET")
            
    
    @config(priority=2) #數(shù)字越大優(yōu)先級(jí)越高
    def list_single_page(self, response):
        #處理當(dāng)前頁(yè)的微博        
        url = "http://weibo.cn/repost/"
        for each in response.doc("div[id^=\"M_\"]").items():             
            mid = each.attr("id")
            self.crawl(url + mid[2:], cookies = response.cookies, callback=self.detail_page) 
            #self.crawl可加上參數(shù)exetime=time.time() + 1*60 (即一分鐘后再crawl)
        
            
    @config(priority=1)
    def detail_page(self, response):
        res = response.doc("#M_")
        
        #判斷是否為轉(zhuǎn)發(fā)
        if len(res.find("span.cmt")) != 0:
            is_rt = 1
        else:
            is_rt = 0
            
        #判斷是否含圖片
        if len(res.children("div").eq(1).find("img")) != 0:
            has_pic = 1
        else:
            has_pic = 0
        
        if is_rt == 0:
            text = res.find("span.ctt").text()
            orig_user = "NA"
            orig_text = "NA"
        else:
            orig_user = res("div:first-child span.cmt a").text()
            orig_text = res.find("span.ctt").text()            
            td = re.findall(r'</span>([\s\S]+)<span class=',res("div:last-child").html())            
            text = PyQuery(td[0]).text()
        return {
            "screen_name":res("div:first-child > a:first-child").text(),
            "time":res.find("span.ct").text(),
            "text":text,
            "is_rt":is_rt,
            "has_pic":has_pic,
            "orig_user":orig_user[1:],
            "orig_text":orig_text,
            "repo_cnt":re.search('\d+',response.doc("span.pms").text()).group(),
            "cmt_cnt":re.search('\d+',response.doc("span.pms").siblings().eq(0).text()).group(),
            "atti_cnt":re.search('\d+',response.doc("span.pms").siblings().eq(1).text()).group()
        } 

這輩子干得最癡漢的事情就是寫(xiě)了個(gè)爬蟲(chóng)把人一千多條微博扒拉下來(lái)了飒箭,感覺(jué)以后再也不會(huì)這么用力愛(ài)一個(gè)人了→_→
……
……
……
好了狼电,我編不下去了蜒灰,這就是科研狗的日常。doge.jpg doge.jpg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肩碟,一起剝皮案震驚了整個(gè)濱河市强窖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌削祈,老刑警劉巖翅溺,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異髓抑,居然都是意外死亡未巫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)启昧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)叙凡,“玉大人,你說(shuō)我怎么就攤上這事密末∥找” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵严里,是天一觀的道長(zhǎng)新啼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)刹碾,這世上最難降的妖魔是什么燥撞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮迷帜,結(jié)果婚禮上物舒,老公的妹妹穿的比我還像新娘。我一直安慰自己戏锹,他們只是感情好冠胯,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著锦针,像睡著了一般荠察。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奈搜,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天悉盆,我揣著相機(jī)與錄音,去河邊找鬼馋吗。 笑死焕盟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耗美。 我是一名探鬼主播京髓,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼航缀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了堰怨?” 一聲冷哼從身側(cè)響起芥玉,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎备图,沒(méi)想到半個(gè)月后灿巧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揽涮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年抠藕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒋困。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盾似,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雪标,到底是詐尸還是另有隱情零院,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布村刨,位于F島的核電站告抄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嵌牺。R本人自食惡果不足惜打洼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逆粹。 院中可真熱鬧募疮,春花似錦、人聲如沸枯饿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奢方。三九已至,卻和暖如春爸舒,著一層夾襖步出監(jiān)牢的瞬間蟋字,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工扭勉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹊奖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓涂炎,卻偏偏與公主長(zhǎng)得像忠聚,于是被迫代替她去往敵國(guó)和親设哗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1 前言 作為一名合格的數(shù)據(jù)分析師两蟀,其完整的技術(shù)知識(shí)體系必須貫穿數(shù)據(jù)獲取网梢、數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)提取赂毯、數(shù)據(jù)分析战虏、數(shù)據(jù)挖掘、...
    whenif閱讀 18,079評(píng)論 45 523
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評(píng)論 25 707
  • 爬蟲(chóng)文章 in 簡(jiǎn)書(shū)程序員專題: like:128-Python 爬取落網(wǎng)音樂(lè) like:127-【圖文詳解】py...
    喜歡吃栗子閱讀 21,758評(píng)論 4 411
  • 你爬了嗎党涕? 要玩大數(shù)據(jù)烦感,沒(méi)有數(shù)據(jù)怎么玩?這里推薦一些33款開(kāi)源爬蟲(chóng)軟件給大家膛堤。 爬蟲(chóng)手趣,即網(wǎng)絡(luò)爬蟲(chóng),是一種自動(dòng)獲取網(wǎng)...
    Albert新榮閱讀 2,229評(píng)論 0 8
  • 離開(kāi)你以后肥荔,才知道你在的意義回懦,我想你,我夢(mèng)你次企,我念你~但我絕不說(shuō)出口怯晕!
    小尼姑1閱讀 101評(píng)論 0 0