大話爬蟲的基本套路


圖片
  

什麼是爬蟲?

網絡爬蟲也叫網絡蜘蛛,若是把互聯網比喻成一個蜘蛛網,那麼蜘蛛就是在網上爬來爬去的蜘蛛,爬蟲程序經過請求url地址,根據響應的內容進行解析採集數據,
好比:若是響應內容是html,分析dom結構,進行dom解析、或者正則匹配,若是響應內容是xml/json數據,就能夠轉數據對象,而後對數據進行解析。html


有什麼做用?

經過有效的爬蟲手段批量採集數據,能夠下降人工成本,提升有效數據量,給予運營/銷售的數據支撐,加快產品發展。前端


業界的狀況

目前互聯網產品競爭激烈,業界大部分都會使用爬蟲技術對競品產品的數據進行挖掘、採集、大數據分析,這是必備手段,而且不少公司都設立了爬蟲工程師的崗位python


合法性

爬蟲是利用程序進行批量爬取網頁上的公開信息,也就是前端顯示的數據信息。由於信息是徹底公開的,因此是合法的。其實就像瀏覽器同樣,瀏覽器解析響應內容並渲染爲頁面,而爬蟲解析響應內容採集想要的數據進行存儲。jquery


反爬蟲

爬蟲很難徹底的制止,道高一尺魔高一丈,這是一場沒有硝煙的戰爭,碼農VS碼農
反爬蟲一些手段:git

  • 合法檢測:請求校驗(useragent,referer,接口加簽名,等)
  • 小黑屋:IP/用戶限制請求頻率,或者直接攔截
  • 投毒:反爬蟲高境界能夠不用攔截,攔截是一時的,投毒返回虛假數據,能夠誤導競品決策
  • ... ...

爬蟲基本套路

  • 基本流程github

    • 目標數據
    • 來源地址
    • 結構分析
    • 實現構思
    • 操刀編碼
  • 基本手段正則表達式

    • 破解請求限制json

      • 請求頭設置,如:useragant爲有效客戶端
      • 控制請求頻率(根據實際情景)
      • IP代理
      • 簽名/加密參數從html/cookie/js分析
    • 破解登陸受權瀏覽器

      • 請求帶上用戶cookie信息
    • 破解驗證碼cookie

      • 簡單的驗證碼可使用識圖讀驗證碼第三方庫
  • 解析數據

    • HTML Dom解析

      • 正則匹配,經過的正則表達式來匹配想要爬取的數據,如:有些數據不是在html 標籤裏,而是在html的script 標籤的js變量中
      • 使用第三方庫解析html dom,比較喜歡類jquery的庫
    • 數據字符串

      • 正則匹配(根據情景使用)
      • 轉 JSON/XML 對象進行解析

python爬蟲

  • python寫爬蟲的優點

    • python語法易學,容易上手
    • 社區活躍,實現方案多可參考
    • 各類功能包豐富
    • 少許代碼便可完成強大功能
  • 涉及模塊包

    • 請求

      • urllib
      • urllib2
      • cookielib
    • 多線程

      • threading
    • 正則

      • re
    • json解析

      • json
    • html dom解析

      • pyquery
      • beautiful soup
    • 操做瀏覽器

      • selenium

實例解析

鬥魚主播排行

  • 目標數據

    • 獲取排行榜主播信息
  • 來源地址

  • 結構分析

    • 經過抓包 [排行榜地址][主播房間地址] (谷歌調試network/charles/fiddler)

      • 得到排行數據接口:https://www.douyu.com/directo...

        • 參數確認(去掉沒必要要參數)
        • cookie確認(去掉沒必要要cookie)
        • 模擬請求(charles/fiddler/postman)
      • 得到主播房間信息數據

        • 發現$ROOM是主播房間信息,在頁面的script標籤的js變量中,可以使用正則工具寫表達式去匹配
  • 實現構思

    • 經過請求 [主播排行接口] 獲取 [排行榜數據]
    • [排行榜數據] 中有主播房間號,能夠經過拼接得到 [主播房間地址]
    • 請求 [主播房間地址] 能夠得到 [$ROOM信息] ,解析能夠得到主播房間信息
  • 操刀編碼

申明:此例子僅做爲爬蟲學習DEMO,並沒有其餘利用


基於python實現爬蟲學習基礎demo

def douyu_rank(rankName, statType):
    '''
        鬥魚主播排行數據抓取
        [數據地址](https://www.douyu.com/directory/rank_list/game)

        * `rankName` anchor(巨星主播榜),fans(主播粉絲榜),haoyou(土豪實力榜),user(主播壕友榜)
        * `statType` day(日),week(周),month(月)
    '''
    if not isinstance(rankName, ERankName):
        raise Exception("rankName 類型錯誤,必須是ERankName枚舉")
    if not isinstance(statType, EStatType):
        raise Exception("statType 類型錯誤,必須是EStatType枚舉")

    rankName = '%sListData' % rankName.name
    statType = '%sListData' % statType.name
    # 請求獲取html源碼 
    rs = rq.get(
        "https://www.douyu.com/directory/rank_list/game",
        headers={'User-Agent': 'Mozilla/5.0'})
    # 正則解析出數據
    mt = re.search(r'rankListData\s+?=(.*?);', rs, re.S)
    if (not mt):
        print u"沒法解析rankListData數據"
        return
    grps = mt.groups()
    # 數據轉json
    rankListDataStr = grps[0]
    rankListData = json.loads(rankListDataStr)
    dayList = rankListData[rankName][statType]
    # 修改排序
    dayList.sort(key=lambda k: (k.get('id', 0)), reverse=False)
    return dayList


def douyu_room(romm_id):
    '''
        主播房間信息解析
        [數據地址](https://www.douyu.com/xxx)
        'romm_id' 主播房號
    '''
    rs = rq.get(
        ("https://www.douyu.com/%s" % romm_id),
        headers={'User-Agent': 'Mozilla/5.0'})
    mt = re.search(r'\$ROOM\s+?=\s+?({.*?});', rs, re.S)
    if (not mt):
        print u"沒法解析ROOM數據"
        return
    grps = mt.groups()
    roomDataStr = grps[0]
    roomData = json.loads(roomDataStr)
    return roomData
    
def run():
    '''
        測試爬蟲
    '''
    datas = douyu_rank(ERankName.anchor, EStatType.month)
    print '\r\n主播排行榜:'
    for item in datas:
        room_id = item['room_id']
        roomData = douyu_room(room_id)
        rommName = None
        if roomData is not None:
            rommName = roomData['room_name']
        roomInfo = (u'房間(%s):%s' % (item['room_id'], rommName))
        print item['id'], item[
            'nickname'], roomInfo, '[' + item['catagory'] + ']'


run()

運行結果:

主播排行榜:

沒法解析ROOM數據
1 馮提莫 房間(71017):今晚來 [英雄聯盟]
2 阿冷aleng丶 房間(2371789):又是我最喜歡的阿冷ktv時間~ [英雄聯盟]
3 勝哥002 房間(414818):勝哥:南通的雨下的我好心累。 [DNF]
4 White55開解說 房間(138286):盧本偉五五開 天天都要很強 [英雄聯盟]
5 東北大鵪鶉 房間(96291):東北大鵪鶉 宇宙第一寒冰 相聲藝術家! [英雄聯盟]
6 老實敦厚的笑笑 房間(154537):德雲色 給兄弟們賠個不是 [英雄聯盟]
7 劉飛兒faye 房間(265438):劉飛兒  月底吃雞 大吉大利 [絕地求生]
8 pigff 房間(24422):【PIGFF】借基地直播,沒OW [守望先鋒]
9 雲彩上的翅膀 房間(28101):翅:仍是抽天空套刺激! [DNF]
10 yyfyyf 房間(58428):無盡的9月,殺 [DOTA2]

Demo源碼地址

相關文章
相關標籤/搜索