1. 程式人生 > >Python模擬微博抽獎機制!中獎十個九個半女生?自動統計男女比例

Python模擬微博抽獎機制!中獎十個九個半女生?自動統計男女比例

今天來寫一個自動計算微博抽獎男女比例的程式碼,很早就應該發這篇了,只是不想蹭熱點(才不是拖更)。

整個的過程大概分為三步:

S1:從抽獎公示頁獲取所有中獎者的微博ID

S2:由每個中獎者的微博ID進入其相應主頁,獲得需要的個人資訊(性別、粉絲數、微博數等)

S3:對收集到的資訊進行相應的彙總分析

接下來一步一步地進行就好了,沒什麼難點和需要注意的地方,權當做是一次很小的練手。

首先每次微博抽獎都會有一個公示連結。形如:http://event.weibo.com/yae/event/lottery/result?pageid=100140E1204222&id=3538105&f=weibo

其中pageid和id兩個變數就可以定位一次抽獎。

中獎名單每頁公示3個,當你點下一頁的時候會以AJAX方式請求資料。

因此我們只需要請求第一頁以後,獲取獲獎的總人數,然後迴圈分別獲取其餘AJAX請求。

 

Python模擬微博抽獎機制!中獎十個九個半女生?自動統計男女比例

 

進學習交流群:548377875   海量學習教程在群檔案,大牛隨時答疑!是一個很不錯的學習交流基地呢!

將每個獲獎人的ID放在一個列表裡,每次append即可。

在這邊有一點就是,我們必須要在登陸狀態下訪問才可以看到獲獎情況,否則會跳轉登入頁。解決辦法是帶cookie訪問。無腦加headers和cookies不會有問題。

def lottery(page, pageid, lid):
 cookies = {# your cookies }
 headers = {# copy the headers }
 params = (
 ('pageid', pageid), # 100140E1198435
 ('id', lid), # 3436763
 ('page', page), # 2
 ('prizeLevel', '1'),
 ('_t', '0'),
 ('__rnd', int(time.time() * 1000)), # 1542650067843
 )
 response = requests.get('https://event.weibo.com/yae/aj/event/lottery/result', headers=headers, params=params,
 cookies=cookies)
 return response.text

我們可以看到AJAX返回的內容是一個JSON,但是這個JSON內的資料卻又沒有那麼的友好,並不是我們常見的直接給出了每個使用者的資料字典,而是給了我們一個HTML標籤包裹的程式碼塊。也就是說需要進一步的解析,不過好在並不複雜,這裡我選擇自己比較熟悉的BS來做,別的解析方法也都可以。

 

Python模擬微博抽獎機制!中獎十個九個半女生?自動統計男女比例

 

 

執行程式碼,我們便可以得到所有中獎使用者ID組成的一個列表了。

def result(pageid, lid):
 userid = []
 jsonObj = json.loads(lottery('1', pageid, lid))
 html = jsonObj['data']['html']
 # print(html)
 bsObj = BeautifulSoup(html, 'lxml')
 # <span class='lottery_published_gray'>113</span>
 spans = bsObj.find_all('span', {'class': 'lottery_published_gray'})
 count = spans[-1].text
 n = int(count) // 3 + 1
 if n == 1:
 dt = bsObj.find_all('dt')
 for each in dt:
 userid.append(each.find('a')['href'].split('/')[3])
 print(userid)
 else:
 for i in range(1, n + 1):
 jsonObj = json.loads(lottery(i, pageid, lid))
 html = jsonObj['data']['html']
 bsObj = BeautifulSoup(html, 'lxml')
 dt = bsObj.find_all('dt')
 for each in dt:
 userid.append(each.find('a')['href'].split('/')[3])
 print(userid)
 return userid

獲取性別要進入到每個使用者的個人資訊頁面。在這裡我們選擇請求手機版頁面,沒有太多雜亂的頁面結構和廣告,反爬也相對寬鬆。

 

Python模擬微博抽獎機制!中獎十個九個半女生?自動統計男女比例

 

 

還是跟剛才差不多,帶cookies請求頁面就好了。這邊的結構很規範,用XPATH也可以,當然如果我們只取性別的話,正則也是夠用的。其餘的資訊像是姓名、地區、生日、標籤、簡介等等,大家可以相應地自己實現。

def userInfo(uid):
 cookies = {# your cookies}
 headers = {# copy the headers}
 response = requests.get('https://weibo.cn/' + uid + '/info', headers=headers, cookies=cookies)
 h = response.text
 # print(h)
 pattern = re.compile(r'性別:(.)')
 sex = pattern.search(h).group(1)
 return sex

如此迴圈得到了所有使用者的性別後,我們只需要統計列表中的男女比例就可以了。

# 大概在300次左右會出現請求失敗。所以如果中間人數特別多的話,還是設定一下延時。

最後就是簡單的資料分析。因為一來資料總量不大,二來我們不打算進行太深入的資料分析,在不考慮儲存的情況下,我們直接使用了列表來存結果。如果要進一步分析,最好還是用字典(JSON)、CSV等方式進行持久化操作。既然是列表儲存的話,我們可以直接用列表的count方法來計算出男女比例。大家也可以結合視覺化方法來更直觀地展示結果。

print(usersex.count('女'))
print(usersex.count('男'))

最終可以看一下兩次抽獎的結果:

usersex1 = ['女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
 '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '男', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
 '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
 '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
 '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
 '女', '女', '女']
usersex2 = ['男', '女', '女', '男', '女', '男', '女', '女', '女', '男', '女', '女', '女', '女', '女', '女', '女', '男', '女', '男', '女', '男',
 '男', '女', '男', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '男', '女', '男', '男', '男', '女',
 '女', '男', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '男', '女', '女', '男', '女', '女', '女', '女', '女',
 '女']

第一次抽獎113人中,有112人為女;第二次抽獎67人中,有51人為女。

今天的內容我也為大家錄了一期視訊講解,大家可以點選原文跳轉觀看,比較適合零基礎的同學學習~