摘要:于是去网上搜一下,搜索结果都是前两年爬取微博的方法,那时候还是用以格式传递,现在明显已经不是。其他的属性是一些微博的标题发送时间内容点赞数评论数转发数和博主相关信息等。
网友:看看胸
女:滚网友:美胸比赛
女:[图片消息]
继上次知乎话题 拥有一副好身材是怎样的体验? 解析了知乎回答内容之后,这次我们来解析一下微博内容,以微博网友发起的美胸大赛为例:
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字符串命名防止重复图片
最后接入某大厂的人体特征值检测,考虑到图片大多没有露脸,识别男女性别不够准,这里只把未识别出人体的图片去掉了(一些表情图)。
有兴趣的可以公众号回复 套图 获得这次微博图片和上次知乎图片本次微博结构比较简单,与上次关于知乎的文章差不多,不再提供源码。
公众号:爱写bug(ID:iCodeBugs)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/45152.html
摘要:本人长期出售超大量微博数据旅游网站评论数据,并提供各种指定数据爬取服务,。如果用户传入伪造的,则新浪微博会返回一个错误。 PS:(本人长期出售超大量微博数据、旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。由于微博接口更新后限制增大,这个代码已经不能用来爬数据了。如果只是为了收集数据可以咨询我的邮箱,如果是为了学习爬虫,...
摘要:本人长期出售超大量微博数据旅游网站评论数据,并提供各种指定数据爬取服务,。如果用户传入伪造的,则新浪微博会返回一个错误。 PS:(本人长期出售超大量微博数据、旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。由于微博接口更新后限制增大,这个代码已经不能用来爬数据了。如果只是为了收集数据可以咨询我的邮箱,如果是为了学习爬虫,...
摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...
摘要:前言利用实现抓取微博评论数据,废话不多说。让我们愉快地开始吧开发工具版本相关模块模块模块模块模块模块以及一些自带的模块。环境搭建安装并添加到环境变量,安装需要的相关模块即可。 ...
阅读 1834·2021-11-11 16:55
阅读 1967·2021-10-08 10:13
阅读 717·2019-08-30 11:01
阅读 2133·2019-08-29 13:19
阅读 3257·2019-08-28 18:18
阅读 2605·2019-08-26 13:26
阅读 555·2019-08-26 11:40
阅读 1836·2019-08-23 17:17