社区抽奖脚本-v1.0

念旧   ·   发表于 2024-06-14 11:54:53   ·   闲聊灌水区

前段时间发表了一篇文章:https://bbs.zkaq.cn/t/31645.html

文章里有抽奖活动,于是写了一个抽奖脚本:

  • 先获取社区某篇文章的所有评论(包括用户名 + 评论时间 + 评论内容)
  • 然后对用户名进行去重,并从中随机抽取幸运儿

下面有脚本的运行过程演示。

脚本参数简介

目前该脚本共支持 5 个参数。

-i/—id

文章的编号,如图所示:

-n/—num

抽奖的人数,例如你要抽 5 份奖品,那就指定参数-n 5或者是--num 5

-t/—timeout

HTTP 请求超时,默认为 10 秒。

—http-proxy

可以指定 BurpSuite 的监听地址,方便调试,例如:--http-proxy 127.0.0.1:8080

—verbose

默认情况下,脚本运行时不会打印所有评论的内容,如果你想查看所有评论的内容,则需要添加--verbose选项。

正常抽奖

以下是脚本演示。(本次是抽奖测试,获奖结果仅供参考)

只需要指定文章编号 以及 抽奖数量即可。

  1. python3 lucky.py -i 编号 -n 数量

对于某些文章,例如未通过审核 或 不存在该主题等情况,则无法进行抽奖。

输出详细信息

如图所示,添加--verbose选项后可以打印所有评论的详细信息。

调试请求

如图所示,指定--http-proxy选项为 BurpSuite 的监听地址,可以代理所有 HTTP 请求。

脚本源代码(附件也有)

我在附件上传了该脚本,可直接下载。

该脚本写的比较简陋,大佬们可以改进改进。

  1. #!/usr/bin/env python3
  2. import requests
  3. import argparse
  4. import random
  5. import os
  6. from bs4 import BeautifulSoup
  7. requests.packages.urllib3.disable_warnings()
  8. proxy = {}
  9. headers = {
  10. 'User-Agent': 'ZKAQ-Lucky'
  11. }
  12. def getPageId(id, timeout):
  13. '''
  14. 获取每篇文章的最大页数
  15. :param id: (int) 文章编号
  16. :param timeout: (int) 请求超时
  17. :return pageid: (int) 返回总页数 (如果没有评论的话则返回 0 并退出运行)
  18. '''
  19. print('[INFO] 获取文章最大页数...')
  20. try:
  21. # ---------- 1. 请求 ----------
  22. url = 'https://bbs.zkaq.cn/t/{0}.html'.format(id)
  23. res = requests.get(
  24. url,
  25. headers=headers,
  26. timeout=timeout,
  27. proxies=proxy,
  28. verify=False
  29. )
  30. # ---------- 2. 解析 ----------
  31. soup = BeautifulSoup(res.text, 'html.parser')
  32. try:
  33. titles = soup.select('.t-info .head h1')
  34. title = titles[0].text.strip()
  35. except:
  36. print('\t[-] 帖子尚未通过审核, 或不存在该主题, 或无法访问')
  37. os._exit(-1)
  38. items = soup.select('#pageid')
  39. pageid = items[0].get('value', 0)
  40. # ---------- 3. 结果 ----------
  41. print('\t[+] 文章链接: ' + url)
  42. print('\t[+] 文章标题: ' + title)
  43. print('\t[+] 评论总页数: ' + str(pageid))
  44. if pageid == 0:
  45. os._exit(-1)
  46. return int(pageid)
  47. except IndexError:
  48. # 单页评论没有 pageid, 会触发索引错误, 所以直接返回 1 页
  49. print('\t[+] 文章链接: ' + url)
  50. print('\t[+] 文章标题: ' + title)
  51. print('\t[+] 评论总页数: 1')
  52. return 1
  53. except Exception as e:
  54. print('\t[-] 请求错误')
  55. print(e)
  56. os._exit(-1)
  57. def getAllComments(id, timeout, pageid, verbose=False):
  58. '''
  59. 获取所有评论的用户名 和 评论内容
  60. :param id: (int) 文章编号
  61. :param timeout: (int) 请求超时
  62. :param pageid: (int) 文章总页数
  63. :param verbose: (bool) 是否显示评论详细信息
  64. :return usernames, times, comments: (list)返回去重后的用户名列表 + (list)评论时间列表 + (list)评论内容列表
  65. '''
  66. print('[INFO] 获取所有评论...')
  67. usernames = []
  68. times = []
  69. comments = []
  70. try:
  71. # ---------- 1. 请求每页评论 ----------
  72. for i in range(1, pageid+1):
  73. url = 'https://bbs.zkaq.cn/t/{0}/{1}.html'.format(id, i)
  74. res = requests.get(
  75. url,
  76. headers=headers,
  77. timeout=timeout,
  78. proxies=proxy,
  79. verify=False
  80. )
  81. # ---------- 2. 解析每页评论 ----------
  82. soup = BeautifulSoup(res.text, 'html.parser')
  83. user_items = soup.select('.comment-list .author')
  84. for user in user_items:
  85. usernames.append(user.text.strip())
  86. time_items = soup.select('.comment-list .time')
  87. for time in time_items:
  88. times.append(time.text.strip())
  89. comment_items = soup.select('.comment-list .markdown-body')
  90. for comment in comment_items:
  91. comments.append(comment.text.strip())
  92. # ---------- 3. 展示所有评论 ----------
  93. if verbose:
  94. for i in range(len(usernames)):
  95. print('{0:25}\t{1:25}\t{2}'.format(usernames[i], times[i], comments[i]))
  96. # ---------- 4. 结果 & 去重 ----------
  97. print('\t[+] 用户名总数: ' + str(len(usernames)))
  98. print('\t[+] 评论总数: ' + str(len(comments)))
  99. usernames = list(set(usernames))
  100. print('\t[+] 去重后的用户名总数: ' + str(len(usernames)))
  101. if verbose:
  102. for i in range(len(usernames)):
  103. print('{0}\t{1}'.format(i+1, usernames[i]))
  104. return usernames, times, comments
  105. except Exception as e:
  106. print('\t[-] 请求错误')
  107. print(e)
  108. os._exit(-1)
  109. def lucky(usernames, num):
  110. '''
  111. 抽奖
  112. :param usernames: (list) 经过去重的用户名列表
  113. :param verbose: (bool) 抽奖数量
  114. '''
  115. print('[INFO] 开始抽奖...')
  116. for i in range(num):
  117. luck = random.randint(0, len(usernames)-1)
  118. print('\t[+] 幸运儿 {0:3}: {1}'.format(i+1, usernames.pop(luck))) # .pop() 会删除并返回元素, 防止重复中奖
  119. def main():
  120. parser = argparse.ArgumentParser()
  121. parser.add_argument('-i', '--id', type=int, help='文章编号, 例如 (-i 31645)', required=True)
  122. parser.add_argument('-n', '--num', type=int, help='抽奖数量, 例如抽取五个人 (-n 5)', required=True)
  123. parser.add_argument('-t', '--timeout', type=int, help='请求超时, default: 10', default=10)
  124. parser.add_argument('--http-proxy', type=str, help='HTTP 代理, 例如 (--http-proxy 127.0.0.1:8080)')
  125. parser.add_argument('--verbose', action='store_true', help='显示详细信息')
  126. args = parser.parse_args()
  127. if args.http_proxy:
  128. proxy['http'] = args.http_proxy
  129. proxy['https'] = args.http_proxy
  130. pageid = getPageId(args.id, args.timeout)
  131. usernames, times, comments = getAllComments(args.id, args.timeout, pageid, args.verbose)
  132. lucky(usernames, args.num)
  133. if __name__ == '__main__':
  134. main()

结语

文章抽奖截止至2024-06-17 00:00:00,帅哥靓女们不来试试吗?

https://bbs.zkaq.cn/t/31645.html

打赏我,让我更有动力~

附件列表

lucky.zip   文件大小:0.002M (下载次数:0)

3 条回复   |  直到 4个月前 | 254 次浏览

嘉名
发表于 4个月前

第十个才是我【泪】

评论列表

  • 加载数据中...

编写评论内容

小瑟斯
发表于 4个月前

想要奖品

评论列表

  • 加载数据中...

编写评论内容

我是大白
发表于 4个月前

看到没,介个,就叫专业!

评论列表

  • 加载数据中...

编写评论内容
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.