专栏首页月小水长用户、话题、评论一网打尽,分享一个最强微博爬虫

用户、话题、评论一网打尽,分享一个最强微博爬虫

实现的功能

微博向来是一个极好的吃瓜圣地,为了获取微博上行行色色的数据,微博相关的爬虫也是层出不穷,因为无论是运营者还是数据分析从业者都或多或少需要微博数据,我的许多朋友也不例外,经过断断续续的努力,我完成了一个可能是史上最强大的微博爬虫的编写。

该爬虫的功能主要分为三部分,第一个主打功能是爬取指定用户的所有微博(可以通过热键 Ctrl + P 快速打开),这个用户可以按照昵称搜索,可以选择是否只抓取原创微博,如下图

爬取的微博内容保存在 csv 文件中,表头包括微博id、微博正文、图片 url、发布位置、发布时间、发布工具和点赞数、评论数、转发数,其中图片 url 里面是所有微博图片的 url 以英文逗号间隔拼接起来的。

第二个主打功能是爬取指定话题下的所有微博(可通过热键 Ctrl+B快速打开),如下图

爬取话题微博保存的 csv 格式大致和爬取用户微博格式类似。

第三个主打功能就是爬取根据微博 id 爬取该微博下的所有评论详情,比如微博 id 为 IaYZIu0Ko 的所有评论为:

除了爬虫的业务逻辑,大家也可以在上面看到,有较为友好的操作界面,方便大家操作。

技术路线

代码共计 1000 余行,不关心技术的同学可以跳过此部分

爬虫部分主要是 通过 Chrome 分析微博页面上的接口,获取接口参数,使用 requests 库模拟请求,需要带上 cookies ,我这个爬虫的大头其实是解析部分,我主要用了 lxml 库,需要解析的东西非常多,差不多 csv 中的每一个字段都需要单独的代码块来解析。

爬虫实现的三个功能:按用户爬取、按话题爬取、爬取微博所有评论,我分别用了三个类来实现,WeiboUserScrapy、WeiboTopicScrapy、WeiboCommentScrapy,三个类都有一些可以复用的函数,但是为了减少类之间的耦合,以及方便打包,我没有复用,这样单独一个类拿出来也能跑,减少了依赖。

再主要是界面模块的编写,我之前一直用 wxPython 编写界面,后来深入学习了 pyqt5 这个库,所以这个爬虫的界面是用 pyqt5 来写的,这里主要用到了 ListView model-view 模型、自定义信号及槽函数和一些常见组件的使用。

爬虫比较耗时,而界面又不允许阻塞,所以必须采用多线程技术,使用自定义信号作为爬虫类和界面类之间沟通的桥梁,比如爬虫开始、结束都会向界面类发出相应的信号完成界面的更新。

目前有个不完善的地方就是,后台任务除了进度框和打印,没有其他可视化查看的方法,而且各任务之间的调度只是简单的先到先服务,后续我会自定义调度器类,完成各种暂停、恢复、优先级处理等各种智能调度以及高级的可视化界面。

核心代码讲解

以 WeiboCommentScrapy 类为例,首先通过正则表达式获取评论总数,

res = requests.get('https://weibo.cn/comment/{}'.format(self.wid),headers=self.headers,verify=False)
commentNum = re.findall("评论\[.*?\]",res.text)[0]
commentNum = int(commentNum[3:len(commentNum)-1])

然后根据评论总数分页

pageNum = ceil(commentNum/10)

接着两层循环,外层遍历页数,内层遍历每一页的评论,最后对每一个评论做解析

for page in range(pageNum):

    result = []

    res = requests.get('https://weibo.cn/comment/{}?page={}'.format(self.wid,page+1), headers=self.headers,verify=False)

    html = etree.HTML(res.text.encode('utf-8'))

    comments = html.xpath("/html/body/div[starts-with(@id,'C')]")

    print('第{}/{}页'.format(page+1,pageNum))

    for i in range(len(comments)):
        result.append(self.get_one_comment_struct(comments[i]))

    if page==0:
        self.write_to_csv(result,isHeader=True)
    else:
        self.write_to_csv(result,isHeader=False)
    # 休眠 1-5 秒,防止被封
    sleep(randint(1,5))

注意看内层循环,看上去每一页都是 10 条评论,实则不然,比如第一页有热门评论,会超过 10 条,最后一页可能没有 10 条,所以内层循环没有用 for i in range(10): 而是 for i in range(len(comments)):。内层循环还调用了一个函数 get_one_comment_struct():其作用是根据 xpath 得到的每一条 comment 元素解析得到我们想要的数据,其中又递归调用了几个自定义解析函数,比如解析得到的时间是诸如“xxx分钟前"、"刚刚",我们需要进一步做字符串处理得到具体时间戳。

由于本爬虫都是用 lxml 库采用 xpath 解析的,里面我遇到了许许多多的实用技巧,会在后续博客做详细展开。

本文分享自微信公众号 - 月小水长(inspurer),作者:BuyiXiao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微博话题爬虫更新:突破 50 页限制

    在上一次更新至今,又出现了不少了 bug,昨天趁着有空更新了代码,这次的更新主要做了三件事

    月小水长
  • 微博全站爬虫修复更新啦!!!

    说一声抱歉,当时那段时间我实在太忙,就没有立刻解决,但是记在备忘录上,但是今天下午终于可以有空闲了,就着手解决了这个问题;问题主要是由微博接口和网页结构的变化引...

    月小水长
  • 500行python代码打造刷脸考勤系统

    “员工刷脸考勤”系统,采用python语言开发,可以通过摄像头添加员工面部信息,这里就涉及到两个具体的个问题,一个是应该以什么样的数据来标识每一个员工的面部信息...

    月小水长
  • 来,一起做个测试小工具

    曾经我们测试组有几十条甚至近百条的测试脚本,每次测试都在茫茫脚本海中寻求自己所需的那一个……

    用户5521279
  • 震惊了,原来这才是Kafka的“真面目”!

    Kafka 是一个分布式消息队列,具有高性能、持久化、多副本备份、横向扩展能力。生产者往队列里写消息,消费者从队列里取消息进行业务逻辑。一般在架构设计中起到解耦...

    奋斗蒙
  • 震惊了,原来这才是Kafka的“真面目”!

    ? 导读:Kafka 是一个分布式消息队列,具有高性能、持久化、多副本备份、横向扩展能力。生产者往队列里写消息,消费者从队列里取消息进行业务逻辑。一般在架构设...

    腾讯大讲堂
  • 完美假期第一步:用Python寻找最便宜的航班!

    这个简单的问题经常会得到一个积极的回复甚至还会额外收到一个或两个冒险的故事。通常来讲,旅行是一种体验新文化和拓宽自己视野的好方法。

    abs_zero
  • 完美假期第一步:用Python寻找最便宜的航班!

    这个简单的问题经常会得到一个积极的回复甚至还会额外收到一个或两个冒险的故事。通常来讲,旅行是一种体验新文化和拓宽自己视野的好方法。

    CDA数据分析师
  • 爬虫面试题 | 系统设计 —— 如何设计一个网页爬虫

    来源:https://juejin.im/post/598d1d3e51882548924134c2

    小Gy
  • 医院信息化智能运维,没有专业DBA也能洞察IT异常

    为了保证业务数据的稳定安全,像金融、医疗等有特殊需求的行业,往往花费重金采购品牌数据库产品,然而,海量繁杂的数据也让企业的IT运维压力大大增加,需要投入具有高端...

    CSS-云解决方案与服务

扫码关注云+社区

领取腾讯云代金券