爬取微博评论内容
继上次知乎话题 拥有一副好身材是怎样的体验?
解析了知乎回答内容之后,这次我们来解析一下微博内容,以微博网友发起的大赛为例:
https://m.weibo.cn/detail/4367970740108457
https://m.weibo.cn/detail/4348022520956497
要获取的微博图片内容,共计672张很凶的照片。
下面是讲如何获取的,不感兴趣的话直接去后台回复 套图 即可获得。
首先进入开发者工具看一下微博结构:
这只是一小部分,微博评论和微博用户发的微博页面,里面都是以html5格式传到本地的,把内容格式化之后就会发现,层级非常复杂,有兴趣的可以看一下,与其解析这个还不如用selenium更简单一些。于是当时就产生了两个思路:
- 借助 splash 直接解析渲染后的页面
- 用 mitmproxy 抓手机APP微博的包,用 APPium 控制手机刷新评论
不管是哪一种,相对于只是获取一下图片而言都麻烦。于是去网上搜一下,搜索结果都是前两年爬取微博的方法,那时候还是用 ajax 以 json 格式传递,现在明显已经不是。
然后后面抱着侥幸心理把访问形式改成手机,微博域名就从 weibo.com
变成了 weibo.cn
,再看一下 network 选项卡以hotflow 开头的 xhr :
这时候 weibo.cn 传给本地信息就是简单的 json 格式啦。上图就是微博评论列表的评论,可以看到每条评论如果有图片,就会有 pic 属性,但是要注意在 pic 下的 直接子 url 只是预览图链接,并非原图。原图链接在pic 属性下 large 下的 url。其他的属性是一些微博的标题、发送时间、内容、点赞数、评论数、转发数和博主相关信息等。我们这次重点是图片,就不管其他的了。
另外微博的反爬措施很强,真的恶心到我了,如果有大规模爬取需求,建议去淘宝买号,建 Cookie池,或者用代理池不停地切换访问主机。如果只用自己电脑本地Cookie,那就把请求头弄全,并限制抓取速度。
切换到 Headers 选项卡,看一下 Request URL
:
https://m.weibo.cn/comments/hotFlowChild?cid=4376866645060411&max_id=152030087630286&max_id_type=0
可以看出它的格式是
https://m.weibo.cn/comments/hotFlowChild?
+ cid
+ max_id
+ max_id_type
'
其中 cid 是每一条微博的唯一ID,max_id 是下一次传回数据的最后一条评论的 ID。也就是往下翻看评论,每次显示十条,并在这次所看的评论里就传回 下十条评论 的最后一条评论的唯一 ID,微博是根据这个 ID 传回下十条内容。这也就直接限制了每次爬评论、微博、二级评论时只能一次获取十条,也无法利用线程池加速,因为只有获取了这十条才知道下十条请求地址里 max_id 的值。
然后就可以由这些信息构造请求,获取 json 格式的响应结果:
comment_url = 'https://m.weibo.cn/comments/hotflow?id={weibo_id}&mid={weibo_id}&max_id={max_id}&max_id_type=0' url = comment_url.format(weibo_id=id, max_id=0) response = requests.get(url, headers=headers) result = json.loads(response.text)
先获取总评论数来计算需要多少次才能爬完评论:
total_number = result.get('data').get('total_number') total_number = int(total_number) for i in range(int(total_number / 10)): result = get_page(weibo_id) for url in parse_comment(result): save_to_img(url)
下载完图片只有700来张才知道靠后的评论都是无用的(男士跟答主要联系方式什么的)评论。
然后就是获取图片地址:
def parse_comment(result): if result.get('ok') and result.get('data').get('data'): comments = result.get('data').get('data') for comment in comments: if comment.get('pic'): url = comment.get('pic').get('large').get('url') yield url
要先 if comment.get('pic')
一下,这很重要,因为很多无用评论并没有配图,也就是没有 pic 属性,要以这种方式过滤掉。
另外还有这个:
这里的二级评论就很有必要爬一下,看一下结构:
值得注意的是二级评论里不管有没有图片都不会有 pic 属性,图片在回答内容text 里以 css 方式嵌套的,很明显就是 a 标签下的 href 属性 就是图片地址。用 pyquery 取出来地址:
childs_comment = result.get('data') for child_comment in childs_comment: text = child_comment.get('text') content = pyquery.PyQuery(text) url = content('a').attr('href') yield url
存储图片以图片内容的 md5 值命名,可以去重:
response = requests.get(url) if response.status_code == 200:img_path = '{0}/{1}.{2}'.format(path,md5(response.content).hexdigest(), 'jpg') # 以图片的md5字符串命名防止重复图片
最后接入某大厂的人体特征值检测,考虑到图片大多没有露脸,识别男女性别不够准,这里只把未识别出人体的图片去掉了(一些表情图)。
有兴趣的可以回复 套图 获得这次微博图片和上次知乎图片
本次微博结构比较简单,与上次关于知乎的文章差不多,不再提供源码。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
LeetCode 26:删除排序数组中的重复项 Remove Duplicates from Sorted Array
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 示例 1: 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 你不需要考虑数组中超出新长度后面的元素。 示例 2: 给定 nums = [0,0,1,1,1,2,2,3,3,4], 函数应该返回新的长度 5, 并且原数组 nums...
- 下一篇
JAVA基于PDF box将PDF转为图片
JAVA基于PDF box将PDF转为图片在一项目中用到,本身我是。NET的,团队中有用到JAVA,故此我处理这个功能,记录以下备用。 1.引用:fontbox-2.0.16.jar、pdfbox-app-2.0.16.jar 版本一定要正确,否则代码会有问题。 main函数: package kevin.cn;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.imageio.ImageIO;import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.PDPage;import org.apache.pdfbox.pdmo...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7设置SWAP分区,小内存服务器的救世主
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库