python實現爬蟲統計學校BBS男女比例(一)

來源:互聯網
上載者:User
一、項目需求

前言:BBS上每個id對應一個使用者,他們註冊時候會填寫性別(男、女、保密三選一)。

經過檢查,BBS註冊使用者的id對應1-300000,大概是30萬的使用者

筆者想用Python統計BBS上有多少註冊使用者,以及這些使用者的性別分布

順帶可以統計最近活動使用者是多少,其中男、女、保密各佔多少

活動使用者的限定為“上次啟用時間”為 2015年

二、最終結果

性別資訊儲存在文本裡,一行表示一個使用者的資訊,各列分別表示
【行數,id(塗掉了),性別,最後活躍時間】

三、實現思路

使用者性別資訊在哪個頁面?

得到下面個人首頁

把後面的uid=256730數字改成其他數字,就可以得到其他人的首頁。

另外,如果上面的連結無法得到性別,可以再通過這個連結,也是修改uid可以訪問其他人首頁。

http://rs.xidian.edu.cn/home.php?mod=space&uid=256730&do=profile

四、資料如何儲存?

用資料庫還是其他方案?

為了閱讀方便,我們考慮用文字檔儲存。

30萬的使用者儲存在一個文本裡會導致文本過大。如果程式被意外終止,30 萬的使用者資料需要重新爬取。

我們我們考慮一個文本裡存放1000條記錄,理論上可以用30個文本來存放30萬條資料。

文本名稱為correct1-1001.txt correct47001-48001.txt,注意:1-1001是[1,1001),包含1,不包含1001

1、使用正則匹配找出性別

查看網頁原始碼

  • 性別
  • 還可以找到啟用時間-->
  • 上次發表時間2015-11-4 20:04
  • 抱歉,您指定的使用者空間不存在

    我們可以利用re模組來進行正則匹配

    sexRe = re.compile(u'em>\u6027\u522b(.*?)\u4e0a\u6b21\u6d3b\u52a8\u65f6\u95f4(.*?))\u62b1\u6b49\uff0c\u60a8\u6307\u5b9a\u7684\u7528\u6237\u7a7a\u95f4\u4e0d\u5b58\u5728<')

    因為中文的原因,需要Unicode 轉換 中文工具,可以用站長工具 Unicode 轉換 ASCII,ASCII 轉換 Unicode,比如下面這個連結: http://tool.chinaz.com/Tools/Unicode.aspx

    • 性別的Unicode 是 \u6027\u522b
    • 上次啟用時間 \u4e0a\u6b21\u6d3b\u52a8\u65f6\u95f4
    • 抱歉,您指定的使用者空間不存在
    • \u62b1\u6b49\uff0c\u60a8\u6307\u5b9a\u7684\u7528\u6237\u7a7a\u95f4\u4e0d\u5b58\u5728

    這兒是簡單擷取性別的原始碼,通過urllib2對連結myurl發送一個get請求,將得到的html儲存下來。注意編碼問題unicode(html, 'utf-8'),然後對html正則匹配seWord。

    如果該使用者有性別資訊,返回對應的性別;否則,返回None

    #對myurl頁面進行seWord匹配尋找#seWord是用unicode表示def getInfo(myurl, seWord):  headers = {    'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'  }  req = urllib2.Request(    url=myurl,    headers=headers  )  time.sleep(0.3)  response = urllib2.urlopen(req)  html = response.read()  html = unicode(html, 'utf-8') #需要進行編碼,否則找不到資訊  timeMatch = seWord.search(html) #因為seWord是用unicode表示  if timeMatch:    s = timeMatch.groups()    return s[0]  else:    return None

    五、錯誤處理

    1、斷網情況(熱修複方案)

    • 總共爬蟲需要幾天時間,用的校園網,中間可能有斷網的可能。
    • 如果發現斷網,我們可以重新連上互連網,這中間有些使用者的性別沒有擷取到。
    • 程式已耗用時間較長,斷一次網就重新從id=1開始跑是不科學的。而且你也不能保證這次就網一直是好的。
    • 為了不讓程式重頭開始跑,所以我們是記錄下斷網中漏掉的使用者id。
    • 等一次程式跑完了(這需要幾天的時間),我們再跑記錄下來的id重新跑一次。

    2、無法擷取性別

    • 這種有兩種情況:
    • 一是真的沒有性別(使用者沒有填寫)
    • 二是伺服器抽了,咱們請求網頁失敗了。
    • 這種咱們也是和上面類似,記錄下失敗的id,後面再重新跑。

    知識點小結

    對於這種錯誤,SyntaxError: Non-ASCII character '\xe5' in file

    需要在檔案開頭加上# -*- coding: UTF-8 -*-

    因為 python 的預設編碼檔案是用的 ANSCII 碼


    BBS網頁原始碼使用utf-8進行編碼的。

    本項目設計到中文字元,自然會遇到編碼問題。

    import sysprint sys.getdefaultencoding()

    輸出 ascii
    從上面的代碼可以看出 sys.defaultencoding 是 ANSCII,ANSCII是無法對中文字元進行編碼的。UTF-8是Unicode的實現方式之一,可以對中文字元進行編碼。遇到中文字元,我們需要加上這行代碼

    reload(sys)# sys.setdefaultencoding('utf-8')

    更改 sys.defaultencoding 為'utf-8'

    後期整理的時候發現了自己一個小問題,因為Regex當時用unicode來表示的,所以需要把html進行unicode轉換進行尋找。
    後來發現可以直接用漢字對原來的html進行尋找。

    # -*- coding: UTF-8 -*-  html = response.read()  sexRe = re.compile('em>性別(.*?)\u6027\u522b(.*?)

    輸出

    字串 女unicode 女  html = response.read()  print len(html)  html = unicode(html, 'utf-8') #  print len(html)

    輸出

    html = response.read()  print len(html)  html = unicode(html, 'utf-8') #  print len(html)

    輸出

    3542333658

    以上就是python實現爬蟲統計學校BBS男女比例的前期準備和方案分析,希望對大家的學習有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.