吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3321|回复: 0
收起左侧

[Python 转载] python分析百家号文章评论并进行爬取

[复制链接]
wuse111 发表于 2021-2-2 12:53
这篇文章是分析百家号的文章评论,并提取下面文章的评论


该文章仅供交流使用,请勿非法使用,如有侵犯,请联系删帖

文章将分为2个板块,分析和代码


一. 分析
选取一篇文章,然后打开开发者工具进行抓包
转到开发者工具的Network,在Filter上输入comment进行筛选,这样做的目的是准确的筛选出有关评论的数据包
(如果没出来的话,可以下图中红框内的进行进一步筛选)
1.jpg
通过上面的筛选发现出现3个包,点进去看一下,发现第一个包是我们所需要的数据,分析第一个数据包里面的一些参数,如图所示

如果在不确定哪些参数是变动的,可以进行再一次抓包对比,最后发现除了start、num、callback和ts变动的,了解js的知道这个callback是个回调函数
是生成的随机字母加数字,这个固定对数据包无影响,而其他参数中ts是13位时间戳,start是页数,但是变动是加上后面num数,所以num是每页的评论数


在返回的结果中发现下图的情况,返回的并不是json的格式,而在写代码的过程中发现了返回的数据是Unicode的返回。后续想通过utf-8的编码后再解码发现行不通,一直报错
后面尝试使用json方式来提取数据,因为除去下图的前面的_boxjsonp0e0bb351()就可以得到完整json,可以使用正则提取出来,然后同json模块load然后提取
image.png





二.代码
代码每段都附上了注释说明,考虑每个楼都有相应的回复者,那么就需要提取对应的回复者。最后选取了用json的方式存储数据


其中在上面返回的数据编码问题上,有好的解决方案可以说明。有错误的话指出来,有什么好的代码写法可以交流一下。


[Python] 纯文本查看 复制代码
  import requests
    import time
    import re
    import json
    import math

    #设置协议头
    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
        "Connection": "close"
    }
    #提取前面的链接cookie值
    res = requests.get(
        "https://www.baidu.com/s?cl=3&tn=baidutop10&fr=top1000&wd=%E4%BA%BA%E6%B0%91%E6%97%A5%E6%8A%A5%3A%\
        E6%89%AB%E7%A0%81%E7%82%B9%E9%A4%90%E4%B8%8D%E8%AF%A5%E6%98%AF%E5%94%AF%E4%B8%80%E9%80%89%E6%8B%A9&rsv_idx=2&rsv\
        _dl=fyb_n_homepage&hisfilter=1",
        headers=headers)
    #提取cookie为字典形式
    cookie = res.cookies.get_dict()
    data_dict = {}
    count = 0
    i = 0
    while True:
        time.sleep(3)
        #生成13位时间戳
        current_milli_time = lambda: int(round(time.time() * 1000))
        now_time = current_milli_time()
        #完善协议头
        headers.update({'Accept': '*/*',
                        'Accept-Encoding': 'gzip, deflate, br',
                        'Accept-Language': 'zh-CN,zh;q=0.9',
                        #设置来路的,不设置这个无法返回评论数据
                        'Referer': 'https://baijiahao.baidu.com/s?id=1690446693112251324&wfr=spider&for=pc'})
        #根据自己的url改变其中的变动参数
        url = f"https://ext.baidu.com/api/comment/v2/comment/list?thread_id=1004000038741948&reply_id=&start={i * 20}&num=20&appid=22862035&order=12&inner_order=9&use_list=1&callback=_boxjsonpcd1d7651&use_uk=1&ts={now_time}"
        i += 1
        res = requests.get(url, headers=headers, cookies=cookie)
        #替换返回内容包含\/的链接
        new = res.text.replace(r"\/", "/")
        #使用正则提取出来
        full_json = "{" + re.search(r'_boxjsonpcd1d7651\(\{(.*?)\}\)', new).group(1) + "}"
        #load已经完整的json
        new = json.loads(full_json)
        #在无法提取数据的时候报错跳出死循环
        try:
            data = new['ret']['list']
        except Exception as e:
            print(e)
            break
        for da in data:
            #count计数几楼
            count += 1
            #提取具体内容,可自己决定提取什么内容
            uname = da['uname']
            like_count = da['like_count']
            text = da['content']
            reply_count = da['reply_count']
            print(f"评论者:{uname}\n评论的内容:{text}\n喜欢数:{like_count}\n")
            reply_list = []
            if reply_count == "0":
                print("该评论无回复数")
            else:
                reply_id = da['reply_id']
                #每页10个,用全部回复数除以10,然后进一整数方式估算出页数,当然这里可以使用死循环
                page = math.ceil(int(reply_count) / 10)
                for n in range(page):
                    time.sleep(3)
                    current_milli_time = lambda: int(round(time.time() * 1000))
                    now_time = current_milli_time()
                    #提取评论中的回复数据,返回的方式和提取跟上面一样
                    new_url = f"https://ext.baidu.com/api/comment/v2/comment/detail?thread_id=1004000038741948&reply_id={reply_id}&start={n * 10}&num=10&appid=22862035&order=9&use_list=0&callback=_boxjsonp370b5194&use_uk=1&ts={now_time}"
                    res1 = requests.get(new_url, headers=headers, cookies=cookie)
                    new1 = res1.text.replace(r"\/", "/")
                    full_json = "{" + re.search(r'_boxjsonp370b5194\(\{(.*?)\}\)', new1).group(1) + "}"
                    new1 = json.loads(full_json)
                    #以防估算出错,用try来避免
                    try:
                        new_data = new1['ret']['list']
                    except Exception as e:
                        print(e)
                        break
                    for rp in new_data:
                        f_uname = rp['uname']
                        f_like_count = rp['like_count']
                        f_text = rp['content']
                        #把所有回复数据用字典的形式放在列表里
                        reply_list.append({"replier": f_uname, "reply_content": f_text, "reply_likes": f_like_count})
            #保存进字典里面
            data_dict.update({f"floor_{count}": {"commenter": uname, "content": text, "like_count": like_count,
                                                 "reply_list": reply_list}})
            print(data_dict)
    #爬取完后进行保存数据
    with open("data.json", "w", encoding="utf-8") as f:
        json.dump(data_dict, f)


分析过程有些地方可能没说到,代码上有附上说明,如果在对返回的数据有更好的解决方法可以交流一下。

如有侵权和不当的地方,请联系删贴,文章仅供交流,谢谢。



免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zhangdashan391 + 1 + 1 谢谢@Thanks!
UPC + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

fanvalen 发表于 2021-2-2 13:03
本帖最后由 fanvalen 于 2021-2-2 13:29 编辑

好把我看错了我又去测试一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 19:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表