爬虫实战——爬取今日头条评论(含源码和成果)

发布于:2025-08-06 ⋅ 阅读:(20) ⋅ 点赞:(0)

目录

引言

AJAX简介

如何查看AJAX发送的请求从而在代码中模拟

第一步 触发评论显示

第二步 循环加载所有内容

第三步 解析DOM结构

引言

        RUC蒟蒻一枚,同学需要今日头条的评论数据,因此我在上次的工作中做了一些拓展。

        先展示爬取成果:

         在上一篇文章今日头条爬虫实战(代码+知识点讲解)-CSDN博客,我们爬取了今日头条的一些基本数据,如标题、正文、点赞数等等,这些内容按F12可以直接在html中呈现,非常容易获取。但是当你想爬取一些评论的时候,你会发现直接爬取的html中没有需要的评论信息。        

        想一下我们是怎么看到所有评论的呢,见下图:

        我们是点击了“查看全部535评论”这个按钮过后,网页才会动态加载所有评论信息,此时你才能按F12后看到相应评论。这是因为现代Web采取了一种叫AJAX的技术,为了更好地帮助你理解和构造请求,下面对这种技术做一个简要介绍。

AJAX简介

        AJAX(Asynchronous JavaScript And XML),是一种使用现有技术组合(主要是 JavaScript 和 XMLHttpRequest 对象)在后台与服务器交换数据并更新部分网页内容,而无需重新加载整个页面的技术。

        异步 (Asynchronous)是AJAX的灵魂所在。意味着浏览器在向服务器发送请求后,不会傻傻地等待响应,而是可以继续执行其他脚本、响应用户操作。当服务器的响应数据返回时,浏览器再通过JavaScript来处理这些数据并更新页面的特定部分。

        当用户在页面上执行某个操作(如点击按钮、滚动页面、在搜索框中输入文字等),JavaScript 代码创建一个用于与服务器通信的核心对象,负责向服务器发送请求,服务器接收到请求并生成和返回响应数据。JavaScript 使用获取到的数据,通过 DOM操作方法,只更新网页中需要变化的那一小部分内容。整个页面的其他部分保持不变。

        那就有办法了!我们只需要模拟AJAX发送一份请求,那怎么构造这个请求呢。

查看AJAX发送的请求从而在代码中构造请求

      以本次爬取评论数据为例(这里楼主偷了懒,大部分用dpsk生成的,所以一股子AI味)

  1. 识别数据源: 使用浏览器的开发者工具,切换到 "Network"标签页,清空所有请求,点击“查看全部535评论”,此时会出现新的请求。

  2. 筛选XHR/Fetch请求 在Network标签页中,筛选 XHR 或 Fetch 类型的请求。这些就是浏览器发出的AJAX请求。

  3. 分析请求 找到包含你所需数据的那个请求。查看它的:

    · URL 这是你需要用爬虫程序模拟请求的真实数据地址。通常包含关键参数。

    · 请求方法 (Method) GET 或 POST

    · 请求头 (Headers): 特别是 User-AgentRefererCookie, 有时还有 Authorization 或特定的 X- 头,这些可能需要在爬虫中设置才能成功请求。

    · 请求参数 (Query String Parameters / Payload): 对于 GET 请求,参数在URL的“ ? ”后面;对于 POST 请求,参数在请求体里。这些参数告诉服务器你要什么数据,是构造爬虫请求的关键。

    · 响应预览 (Preview/Response): 查看服务器返回的数据格式(通常是JSON),确认它包含你需要的目标信息。
  4. 模拟请求: 在你的爬虫程序中:

    • 使用 requests.get() 或 requests.post() 向步骤3中找到的真实数据URL发起请求。

    • 在请求中设置必要的请求头(模拟浏览器行为)。

    • 对于 GET 请求,将参数构造成URL的查询字符串。

    • 对于 POST 请求,将参数构造成字典或JSON字符串,作为 data 或 json 参数传递给 requests.post()

  5. 解析响应: 服务器返回的响应通常是JSON格式。使用 response.json() 方法将其解析成Python字典或列表,然后像操作普通字典/列表一样提取你需要的数据。

  6. 处理分页/动态参数: AJAX加载的内容通常分页或需要特定参数(如时间戳、token)。你需要观察多个请求,找出参数变化的规律,在爬虫中构造这些参数来获取后续数据。

 明白了原理过后,下面是实际代码中重要步骤的大致讲解:

第一步 触发评论显示

即模拟用户行为进行滚动+点击按钮

# 模拟用户行为:滚动到底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

# 点击"查看全部评论"按钮
comment_btn = driver.find_element(By.CLASS_NAME, "side-drawer-btn")
comment_btn.click()

第二步 循环加载所有内容

        我们发现评论区的每一条评论下面有多条回复,需要我们不断点击“查看更多回复”来获取所有评论信息。

# 不断点击"查看更多",直到没有新内容
while True:
    more_buttons = driver.find_elements(By.CLASS_NAME, "check-more-reply")
    if not more_buttons:
        break  # 没有更多了
    
    for button in more_buttons:
        button.click()  # 继续加载
        time.sleep(2)   # 等待新内容

第三步 解析DOM结构

        我们想在爬取结果表示A评论是B评论的回复这种父子关系,单靠识别 “@XXX” 这种模式是欠妥的,需要先探测一下评论区中父评论和回复评论形成的代码结构,结构模式如下:

<!-- 主评论 -->
<div class="comment-info">
    <div class="content">这是主评论</div>
    
    <!-- 回复评论容器 -->
    <div class="replay-list">
        <div class="comment-info">回复1</div>
        <div class="comment-info">回复2</div>
    </div>
</div>

        因此我们可以通过CSS选择器精准识别这种层级关系。

# 主评论:不在replay-list内的comment-info
main_comments = driver.find_elements(
    By.CSS_SELECTOR, 
    ".comment-info:not(.replay-list .comment-info)"
)

# 回复评论:在replay-list内的comment-info
for main_comment in main_comments:
    replies = main_comment.find_elements(
        By.CSS_SELECTOR, 
        ".replay-list .comment-info"
    )

        以上就是个人在这次实践中认为比较重要的点了,更详细的代码和成果我已经放到了GitHub上KKqdtjo/Toutia-Crawler-Practice,按需自取,祝一切顺利。


网站公告

今日签到

点亮在社区的每一天
去签到