CSDN评论区粉丝抽奖程序1.0【python萌新极简主义自制版】


前言

为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码以及可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

一、机缘巧合

  • 近期我开始着手于粉丝福利送书活动,需要在评论区随机抽取一些粉丝送出实体好书。为了完成这个任务,我需要手动复制粘贴粉丝的名字,并下载相应的抽奖程序,然后手动录入粉丝名单,这一系列繁琐的操作让我觉得非常麻烦
  • 无独有偶,我最近正在实习中,有机会接触和学习有关Python的知识。我初步学习了一些Python爬虫技术,能够简单地爬取一些网页数据。于是,我决定尝试着动手实现一个简易的Python爬虫程序,用于自动获取评论区粉丝的名字,并实现随机抽取的功能
  • 请大家见谅,因为我是Java选手,刚刚入门Python,所以水平有限,程序设计的过程中难免有不足之处,欢迎大家大提出宝贵意见和批评指正

二、 设计思路

  • 首先,我计划使用Python爬虫技术从评论区获取粉丝的名字。通过分析评论区的网页结构,我可以编写爬虫程序来提取相关数据。使用Python的请求库(如Requests)和解析库(如BeautifulSoup),我可以发送请求并从页面中提取所需信息,例如粉丝的用户名。
  • 一旦获取到了粉丝名字的列表,接下来我可以使用Python的随机化库(如random)来实现随机抽取的功能。通过调用适当的方法,我可以从粉丝名字的列表中随机选择若干位粉丝作为获奖者。

三、前置知识

1. 如何发送get请求解析url(基础)

  • 要解析 Python 中 Request 返回的 HTML DOM,你可以使用解析库,如 BeautifulSoup 或 lxml,来处理 HTML 文档。下面是使用 Beautiful Soup 的示例代码:
  • 首先,确保你已经安装了所需的库。对于 Beautiful Soup,你可以使用 pip install beautifulsoup4 进行安装。
  1. BeautifulSoup 是一个 Python 库,用于网络爬虫目的。它提供了一种方便和高效的方式来从 HTML 和 XML 文档中提取数据。使用 BeautifulSoup,你可以解析和遍历 HTML 结构,搜索特定元素,并从网页中提取相关数据。
  2. 该库支持不同的解析器,如内置的 Python 解析器、lxml 和 html5lib,允许你根据特定需求选择最适合的解析器。BeautifulSoup 的优势在于它能够处理格式混乱或损坏的 HTML 代码,使其成为处理复杂情况下的网络爬虫任务的强大工具。
import requests
from bs4 import BeautifulSoup

# 发送请求获取 HTML
response = requests.get(url)
html = response.text

# 创建 Beautiful Soup 对象
soup = BeautifulSoup(html, 'html.parser')

# 通过选择器选择 DOM 元素进行操作
element = soup.find('div',id='my-element')
  • 在上面的示例中,requests.get(url) 发送请求并获取HTML响应。然后,我们使用 response.text 获取响应的HTML内容,并将其传递给 Beautiful Soup 构造函数 BeautifulSoup(html, ‘html.parser’),创建一个 Beautiful Soup 对象 soup
  • 接下来,你可以使用 Beautiful Soup 提供的方法和选择器,如 find(),来选择 HTML DOM 中的特定元素。在上述示例中,我们通过find方法 find() 选择具有 idmy-element 的元素。

2. 如何发送post请求解析url

解析一个请求主要关注以下几个方面

  • 请求类型(post、get…)
  • 请求路径(网址)
  • 请求头(如图)

在这里插入图片描述

  • 请求参数(post请求是隐式参数,而浏览器发送的是get请求,这意味着发post请求的接口数据无法通过发get请求直接获取到

以下是一个示例代码

import json

import requests
def main():
    #这是获取广州青年报响应数据的一个模拟测试类
    url = 'https://www.gzyouthnews.org.cn/index/index'
    header = {
    
    
        'X-Requested-With':'XMLHttpRequest'
    }
    data={
    
    
        'act':'list',
        'date':'2023-08-10',
        'paper_id':1
    }
    res = requests.post(url=url,headers=header,data=data)
    list = json.loads(res.text)
    for i in list:
        print(i.get('edition'))

if __name__ == '__main__':
    main()

3. 如何添加常用的请求头

  • 如果想在实际的代码中设置HTTP请求头,可以通过使用相应编程语言和HTTP库的功能来完成。下面是一个示例,显示如何使用Python的requests库添加常用的请求头:
import requests

url = "https://example.com"
headers = {
    
    
    "User-Agent": "Mozilla/5.0",
    "Accept-Language": "en-US,en;q=0.9",
    "Referer": "https://example.com",
    # 添加其他常用请求头...
}

response = requests.get(url,stream=True, headers=headers)
  • 在上述示例中,我们创建了一个headers字典,并将常用的请求头键值对添加到字典中。然后,在发送请求时,通过传递headers参数将这些请求头添加到GET请求中。
    请注意,实际使用时,可以根据需要自定义请求头部。常用的请求头包括 “User-Agent”(用户代理,用于识别客户端浏览器/设备)、“Accept-Language”(接受的语言)、“Referer”(来源页面)等。

4. 字符串格式化

字符串格式化是一种将变量或数据插入到字符串中的方法,以创建具有特定格式的文本。在Python中,字符串格式化可以通过多种方式实现。

1. 百分号(%)操作符
一种常用的字符串格式化方式是使用百分号(%)操作符。这种方法使用占位符来表示要插入的变量,并在%操作符后面提供相应的值。例如:

name = "Alice"
age = 25
message = "My name is %s and I am %d years old." % (name, age)
print(message)

输出结果将是:

My name is Alice and I am 25 years old.

在上面的例子中,%s是字符串占位符,%d是整数占位符。%操作符后的括号中依次提供了要插入的变量(name和age)。

5. 如何解析JSON格式

  • 要获取 JSON 数据中的 title 属性的值,你可以使用 Python 的 json 模块来解析 JSON 数据。在你的示例数据中,title 属性位于 data 字典中的 pageArticleList 列表中的每个元素中。
  • 下面是一个示例代码,演示如何获取 title 属性的值:
import json

# 假设你已经获取到了 JSON 数据,将其存储在 json_data 变量中
json_data = '''
{
  "status": 200,
  "message": "success",
  "datatype": "json",
  "data": {
    "pageArticleList": [
      {
        "indexnum": 0,
        "periodid": 20200651,
        "ordinate": "",
        "pageid": 2020035375,
        "pagenum": "6 科协动态",
        "title": "聚焦“科技创新+先进制造” 构建社会化大科普工作格局"
      }
    ]
  }
}
'''

# 解析 JSON 数据
data = json.loads(json_data)

# 提取 title 属性的值
title = data["data"]["pageArticleList"][0]["title"]

# 输出 title 属性的值
print(title)
  • 在上述示例中,我们将示例数据存储在 json_data 字符串中。然后,我们使用 json.loads() 函数将字符串解析为 JSON 数据,将其存储在 data 变量中。

  • 然后,我们可以通过字典键的层级访问方式提取 title 属性的值。在这个示例中,我们使用 data[“data”][“pageArticleList”][0][“title”] 来获取 title 属性的值(类似于数组,一个层级就用一个[])。

  • 最后,我们将结果打印出来或根据需求进行其他处理。

  • 或者是用get()获取具体属性的值

list = json.loads(res.text)
    for i in list:
        print(i.get('edition'))

在这里插入图片描述

四、开始编程探索

  • 首先我们按照上面给的模板去编写代码,编写一个发送 get 请求的示例程序,这里以我个人的博客 《4个维度讲透ChatGPT技术原理,揭开ChatGPT神秘技术黑盒【文末送书】》 为例子,先找到对应的 dom 节点
    在这里插入图片描述

在这里插入图片描述

  • 进行代码调试,查找是否正常获取到了我们想要的节点

在这里插入图片描述

  • 我们发现包含所有评论区粉丝名称的 id 为 pcCommentSideBox 的 dom 节点内容为空,并没有发现在页面上看到的其他 dom 结点。
  • 其实到这里我们可以根据经验知道,评论区的数据是通过接口渲染上去的,而不是直接渲染在页面的 dom 结构中,于是我们去网页上的控制台去找对应的数据渲染接口

在这里插入图片描述

  • 通过一条一条查看请求,我们终于找到了对应的渲染评论区数据的返回 json 数据格式的请求

在这里插入图片描述

  • 并且通过查看该请求的消息头,我们不难发现该请求的请求类型为 POST,并且该API接口的请求路径为

https://blog.csdn.net/phoenix/web/v1/comment/list/132666724?page=2&size=10&fold=unfold

在这里插入图片描述

  • 我们直接去访问该接口,发现只有10条数据,并不是完整的评论区的数据

在这里插入图片描述

  • 当你回过头仔细查看页面你会发现,随着你点击查看更多评论,类似的请求也会越来越多

在这里插入图片描述

  • 当你去比对他们的请求路径你会发现,他们之间的区别就是路径中的page参数不同而已,不难推断,一个 page 就是一个页面,当把所有的 page 都集齐了,就获取到了评论区的所有的评论,进一步也就能获取到评论区所有粉丝的名字

在这里插入图片描述

  • 于是,我们将原来的 GET 请求改为 POST 请求,并将路径中的 page 参数通过动态拼接赋值+for循环遍历所有的页面,示例如下
    #假设有20页评论
    for index in range(0,20):
      # 示例博客地址
      url = "https://blog.csdn.net/phoenix/web/v1/comment/list/132666724?page=%s&size=10&fold=unfold" % (index)
  • 此处不加请求头是访问不到带有 JSON 数据的接口的,故在这里添加了常用的请求头,如果还不行,考虑多加几个常用的请求头和加参数
      headers = {
    
    
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
      }
      response = requests.get(url,headers=headers)

在这里插入图片描述

  • 能访问到接口后通过for循环处理每一页的JSON数据

在这里插入图片描述

      html = response.text
      json_data = json.loads(html)
      list = json_data["data"]["list"]
      for item in list:
          # 获取评论区每一条评论中粉丝的用户昵称
          user_name = item["info"]["nickName"]
  • 在访问接口之前定义一个数组nums,用来存储获取到的用户昵称
nums = []
...
nums.append(user_name)
  • 通过 python 的 random 函数随机从存储了评论区所有粉丝用户昵称的数组 nums 中抽取 5 位幸运粉丝
#假设是抽5名幸运粉丝
    for index in range(0,5):
        luck_fan = random.choice(nums)
        print("第" + str(index) + "位幸运粉丝是" + luck_fan)
  • 为了优化用户体验,我们将抽取粉丝数量和访问带有 JSON 数据接口的数量(有多少页就有多少个接口,通过转换为多少条评论来优化用户体验)通过键盘输入的方式,由用户自定义参数,降低代码的耦合度,提升程序与用户的交互性
 #一共有多少条评论,一个页面10条评论
    comment_num = input("请输入博客中的评论数量: ")
    comment_num = int(comment_num)
    luck_fans_num = input("请在键盘输入最终中奖粉丝的数量: ")
    luck_fans_num = int(luck_fans_num)
    
    #有多少页评论循环多少次
    for index in range(0, int(comment/10 + 1)):
    ...
    
    #假设是抽5名幸运粉丝
    for index in range(0,luck_fans_num):
     ...
  • 同时,为了避免最终结果出现两个相同的名字,还得做一下去重工作
 final_nums = []
    #假设是抽5名幸运粉丝
    for index in range(0,luck_fans_num):
        luck_fan = random.choice(nums)
        if luck_fan not in final_nums:
            final_nums.append(luck_fan)
        else:
            index = index - 1
            continue

五、最后,变完全体

import json
import random
import requests


def main():
    nums = []
    #一共有多少条评论,一个页面10条评论
    comment_num = input("请在键盘中输入博客中的评论数量: ")
    comment_num = int(comment_num)
    luck_fans_num = input("请在键盘中输入最终中奖粉丝的数量: ")
    luck_fans_num = int(luck_fans_num)
    for index in range(0, int(comment_num/10 + 1)):
      # 示例博客地址
      url = "https://blog.csdn.net/phoenix/web/v1/comment/list/129956257?page=%s&size=10&fold=unfold" % (index)
      # 发送请求获取 HTML
      headers = {
    
    
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
      }
      response = requests.get(url,headers=headers)
      html = response.text
      json_data = json.loads(html)
      list = json_data["data"]["list"]
      for item in list:
          # 获取评论区每一条评论中粉丝的用户昵称
          user_name = item["info"]["nickName"]
          nums.append(user_name)

    final_nums = []
    #假设是抽5名幸运粉丝
    for index in range(0,luck_fans_num):
        luck_fan = random.choice(nums)
        if luck_fan not in final_nums:
            final_nums.append(luck_fan)
        else:
            index = index - 1
            continue
        print("第" + str(index+1) + "位幸运粉丝是 >>>>>> " + luck_fan)

if __name__ == '__main__':
    main()

在这里插入图片描述
别忘了路径中的page=%s,进行动态拼接

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

猜你喜欢

转载自blog.csdn.net/HHX_01/article/details/132764839