前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python自动统计微博抽奖中奖男女比例(附代码)

Python自动统计微博抽奖中奖男女比例(附代码)

作者头像
不二小段
发布2018-12-19 10:03:00
8590
发布2018-12-19 10:03:00
举报
文章被收录于专栏:不二小段不二小段

今天来写一个自动计算微博抽奖男女比例的代码,很早就应该发这篇了,只是不想蹭热点(才不是拖更)。

整个的过程大概分为三步:

S1:从抽奖公示页获取所有中奖者的微博ID

S2:由每个中奖者的微博ID进入其相应主页,获得需要的个人信息(性别、粉丝数、微博数等)

S3:对收集到的信息进行相应的汇总分析

接下来一步一步地进行就好了,没什么难点和需要注意的地方,权当做是一次很小的练手。

首先每次微博抽奖都会有一个公示链接。形如:http://event.weibo.com/yae/event/lottery/result?pageid=100140E1204222&id=3538105&f=weibo

其中pageid和id两个变量就可以定位一次抽奖。

中奖名单每页公示3个,当你点下一页的时候会以AJAX方式请求数据。

因此我们只需要请求第一页以后,获取获奖的总人数,然后循环分别获取其余AJAX请求。

将每个获奖人的ID放在一个列表里,每次append即可。

在这边有一点就是,我们必须要在登陆状态下访问才可以看到获奖情况,否则会跳转登录页。解决办法是带cookie访问。无脑加headers和cookies不会有问题。

代码语言:javascript
复制
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来做,别的解析方法也都可以。

运行代码,我们便可以得到所有中奖用户ID组成的一个列表了。

代码语言:javascript
复制
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

获取性别要进入到每个用户的个人信息页面。在这里我们选择请求手机版页面,没有太多杂乱的页面结构和广告,反爬也相对宽松。

还是跟刚才差不多,带cookies请求页面就好了。这边的结构很规范,用XPATH也可以,当然如果我们只取性别的话,正则也是够用的。其余的信息像是姓名、地区、生日、标签、简介等等,大家可以相应地自己实现。

代码语言:javascript
复制
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方法来计算出男女比例。大家也可以结合可视化方法来更直观地展示结果。

代码语言:javascript
复制
print(usersex.count('女'))
print(usersex.count('男'))

最终可以看一下两次抽奖的结果:

代码语言:javascript
复制
usersex1 = ['女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
       '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '男', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
       '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
       '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
       '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女', '女',
       '女', '女', '女']

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 不二小段 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档