爬蟲再探實戰(五)———爬取APP數據——超級課程表【一】


    關於爬蟲,開始以為只能爬取網頁數據,后來知道APP也能抓取。於是,在學校利用空閑時間,耗時兩周實現了數據的抓取和簡單的數據分析。

    目標,抓取超級課程表XX大學(其實是我們大學啦。。。)學生20000條發帖信息。思路如下:

    STEP1:為我們的爬蟲找到入口

    APP請求數據,也是通過網絡協議,這樣,我們就抓包來定位入口,這里我用的是fiddler。關於設置手機和fiddler的關聯,請參考這篇文章

找到登陸入口為:http://120.55.151.61/V2/StudentSkip/loginCheckV4.action

    STEP2:登陸

    這里登陸就和模擬登陸原理是一樣的,即向登陸入口POST登陸數據,而且這里還更加簡單,因為fiddler抓包(為了避免搞亂思路,這里抓包分析就先略過了,以后有時間再補上抓包分析這塊吧。。。)可以直接獲取POST的數據,省去了自己構建表單的步驟,具體參見下文代碼。登陸成功后,會返回json數據,里面是你的個人信息。

 

    STEP3:定位數據來源

    要抓取的是發帖信息,手機點擊,fiddler抓包定位。這里定位的入口為:http://120.55.151.61/Treehole/V4/Cave/getList.action,POST方式,數據同樣以json形式返回。要注意的是,這里要想做持續請求,必須搞定時間戳,簡單說就是從第N次請求獲取返回數據的中的一個時間戳,之后應用於第N+1次請求,如此循環,具體請參考代碼。同樣,按照我習慣的方式,用了一個簡單的遞歸來實現循環抓取。

    STEP4:解析json文件,清洗數據並保存

    這里我還是用的EXCEL表格,建議用數據庫。。。因為數據量大的時候(此次抓取包含發帖內容,數據量不算太小。。。),打開EXCEL表格時會巨卡。。。

    有了前面的思路,抓取就是體力活了。。。上代碼:(聲明:出於隱私和安全考慮,代碼中logindata和初始req_data有改動,這個要換成自己抓包得到的數據才可以)

 

import requests
import json
import re
import time
import simplejson
import xlsxwriter


workbook = xlsxwriter.Workbook('kebiao_test.xlsx')
worksheet = workbook.add_worksheet()
worksheet.set_column('A:A', 10)
worksheet.set_column('B:B', 20)
worksheet.set_column('C:C', 5)
worksheet.set_column('D:D', 20)
worksheet.set_column('E:E', 20)
worksheet.set_column('F:F', 500)

worksheet.write(0,0,'學校')
worksheet.write(0,1,'主題')
worksheet.write(0,2,'性別')
worksheet.write(0,3,'日期')
worksheet.write(0,4,'時間')
worksheet.write(0,5,'內容')

# 登陸部分
# 用requests.Session()記錄cookie
s = requests.Session()
loginurl = 'http://120.55.151.61/V2/StudentSkip/loginCheckV4.action'
logindata = 'phoneBrand=Xiaomi&platform=1&deviceCode=867711022104024&account=6603135B883F9B40DED6374A22593&phoneVersion=19&password=98A09B5680DF25A934ACF9B3614AF4EA&channel=XiaoMiMarket&phoneModel=HM+2A&versionNumber=7.4.1&'
headers = {
   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
   'User-Agent': 'Dalvik/1.6.0 (Linux; U; Android 4.4.4; HM 2A MIUI/V7.3.1.0.KHLCNDD)',
   'Host': '120.55.151.61',
   'Connection': 'Keep-Alive',
   'Accept-Encoding': 'gzip',
   'Content-Length': '213',
}

# 提交登陸信息,開始登陸
data = s.post(url=loginurl, data=logindata, headers=headers, stream=True, verify=False)
loginResult = data.text
# 打印登陸信息,檢查是否登陸成功
# 成功后返回個人信息
print(loginResult)


# 定義一個函數,獲取信息並保存
# 傳入要POST的表單數據,即req_data
def get_data(req_data):
   req_url = 'http://120.55.151.61/Treehole/V4/Cave/getList.action'
   data_r = s.post(url=req_url, data=req_data, headers=headers)
   data_r = data_r.text
   # 返回的布爾值為小寫,這里轉化為真正的布爾值
   true = True
   false = False
   
   # 簡單處理json數據,直接解析好像有編碼問題,不太清楚。。。
   data_j = eval(data_r)
   data_js = json.dumps(data_j)
   data_dict = simplejson.loads(data_js)

   # 獲取時間戳
   data = data_dict['data']
   timestampLong = data['timestampLong']
   #print(timestampLong)
   messageBO = data['messageBOs']
   
   # 處理抓到的json數據,拿到目標數據並保存
   for each in messageBO:
      if 'studentBO' in each:
         print(each)
         #topicDict = {}
         if each.get('content', False):
            schoolNamex = each["schoolName"]
            worksheet.write(i,0,schoolNamex)
            tag = each['moodTagBO']['moodTagName']
            worksheet.write(i,1,tag)
            genderx = each['studentBO']['gender']
            worksheet.write(i,2,genderx)
            contentx = each['content']
            #print(contentx)
            worksheet.write(i,5,contentx)
            #topicDict['messageId'] = each['messageId'
            time_f = list(time.localtime(int(str(each['issueTime'])[:-3])))
            time_s = str(time_f[0])+'/'+str(time_f[1])+'/'+str(time_f[2])

            h = time_f[3]
            m = time_f[4]
            sec = time_f[5]
            if h < 10:
               h = '0'+str(h)
            if m < 10:
               m = '0'+str(m)
            if sec < 10:
               sec = '0'+str(sec)
            time_t = str(h)+':'+str(m)+':'+str(sec)
            datex = time_s
            # print(datex)
            worksheet.write(i,3,datex)
            worksheet.write(i,4,time_t)

            i += 1
            global i
   # 用獲取的時間戳構建新的POST表單數據,持續循環抓取
   new_req_data = 'timestamp='+str(timestampLong)+'&preMoodTimestap=1461641185406&phoneBrand=Xiaomi&platform=1&phoneVersion=19&channel=XiaoMiMarket&phoneModel=HM+2A&versionNumber=7.4.1&'
   print('--------------------------new page-------------------------------')
   #print(new_req_data)
   # 定義抓取發帖條數
   if i <= 20000:
      try:
         get_data(new_req_data)
      except:
         print('fail')
      finally:
         workbook.close()

   else:
      workbook.close()
      print('全部抓取成功了!!!')


# i 是抓取條數的標識   
i = 1
# 此處傳入第一個頁面的POST數據,之后展開循環
get_data(req_data='timestamp=146646454916&preMoodTimestap=1461641185406&phoneBrand=Xiaomi&platform=1&phoneVersion=19&channel=XiaoMiMarket&phoneModel=HM+2A&versionNumber=7.4.1&')

 

    代碼輸出結果如下:

 

    EXCEL表格數據如下:

    至此,抓取算是全部搞定。但是,本人畢竟學統計的,有數據怎能不分析呢,下一篇我來講下怎么對數據進行簡單的可視化。


免責聲明!

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



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