由于CSDN太过垃圾的审核,迁移到这边。
无趣的前言
本职工作不是爬虫,但由于一些缘由,近期做了许多关于微博爬虫的事情,差不多把可以爬到的东西摸索了一遍,之后准备写下微博爬虫系列博客,主要包括几方面内容:
- 微博热门内容及榜单的博文爬取 微博爬虫系列之微博榜单博文爬取
- 定向关键词及指定用户博文爬取 微博爬虫系列之关键词及指定用户博文爬取
- 博文评论爬取 微博爬虫系列之博文评论爬取
- 微博用户信息爬取
具体爬取的过程,有一些是自己摸索出来的,有一些是借鉴了一个很强的github资源,后续博客写了之后再慢慢放上来~
关于爬取的途径,包括微博的三个端:
- 微博pc端:https://weibo.com
- 微博网页版:https://weibo.cn
- 微博移动端:https://m.weibo.cn
三个端的爬取都有进行了一些尝试,后面只用了网页版跟移动端。pc端的话,主要是当时进行了用户信息的爬取,需要用到selenium
。但后面发现发现网页版跟移动端已经可以满足了,就没用pc端进行爬取了。
以下夹杂着各种废话,主要是方便后来想用可以看,不喜勿喷。
正文
这篇先写下关于微博热门内容以及其他榜单的博文爬取。在网上搜索的过程中发现许多并不符合自己的要求,所以这部分的爬取基本就是在看过一些检索内容后,自己再慢慢摸索出来的。
热门内容及其他榜单博文爬取方面,用的是微博移动端(https://m.weibo.cn)。对于微博移动版中热门内容、榜单的爬取,不需要使用到cookies
。
热门内容及其他榜单的爬取中,具体的内容细节抓取基本差不多,主要是链接跟进入数据的一些控件有区别,所后来面有部分内容不再赘述。
先介绍热门内容中博文的爬取。
微博热门内容博文爬取
数据来源
第一进入微博移动端(https://m.weibo.cn),打开开发者模式,找到这个文件,就可以找到对应的微博热门内容接口:
https://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0
这个链接代表的是热门内容的首页,由于热门内容是随即滚动的,并且带必定的推荐功能,会随登陆账号的不同显示不一样,每次刷新也都会有不同的数据出现。
进去后可以看到,移动端是用滑动的模式,而不是翻页的模式,那么怎么获取下一页的内容呢?
在网上检索时,会有一些用直接用页数来更新,这边虽然凑巧是这样子的规则,但在爬取关注及粉丝数的时候,发现该字段并不直接用页数取代。因此这里我并不直接用固定思维里的页数进行爬取。
微博中会有一个since_id
的字段,类似page
,用来标志页面。每个对应网页会出现下一页的since_id
,我们就可以利用这个信息获取到下一页的网页链接。在关注、粉丝数爬取中,最后没有下一页的情况下,下一页的since_id
会获取不到。但在热门内容这些地方貌似是无穷无尽的,但我还是设置了一个判断语句。这个在后面的爬取过程中再详细说明。
爬取过程详解
第一依据将前面找到的数据接口爬下数据,看看数据格式。
这里微博是将这些数据用接口的形式滚动存储,直接使用requests
就可以拿到页面数据,数据以json
格式存储。
下面的get_random_ua()
是一个随机获取user-agent
的函数,里面放了一些各种浏览器的user-agent
,直接改成自己的就可以了。
import re
import time
import pandas as pd
import requests
from urllib import request
headers = {
"user-agent": get_random_ua(),
}
url = https://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0
res = requests.get(url, headers = headers)
data = res.json()[ data ]
这里的变量data
后面并没用到,只是看下里面是啥东西:
前面提到的since_id
就放在cardlistInfo
中:
从这里可以获得微博的来源、一般显示的个数(实际爬取并不止这个数,感觉是由于爬取是在整个数据库调,这个个数应该是刷微博时榜单里的内容数)以及下一页的since_id
:
items = res.json()[ data ][ cardlistInfo ]
totalNum = items[ total ] # 榜单数量
title_top = items[ title_top ] # 榜单来源
statistics_from = items[ statistics_from ] # 榜单来源,与前面一致,不需要重复获取
## 获取下一页的since_id
try:
next_since_id = items[ since_id ]
except:
next_since_id = None
## 下一页url
next_url = https://m.weibo.cn/api/container/getIndex?containerid=102803&openApp=0&since_id={} .format(since_id)
下面是具体的内容了
具体博文存储在cards
中,里面放了10条博文:
点开每个元素里面长这样:
博文具体信息就在mblog
中,这里面存储的东西会因博文的不同而变动,所以这边就不展示里面的东西了,==在爬的过程中自己多看看各个控件里是啥!==
这里直接放我爬的一些东西以及自己理解的意思,savePics()
是自己写的一个下载图片的函数。
主要需要的一般就用户id、用户名、博文内容、点赞数、转发数、回复数。
需要博主信息可以直接在mblog
里的user
获取,里面包括许多信息,具体的意思后面爬取用户信息再介绍~
其他需要的信息根据需求自行在这里面探索吧~
cards = res.json()[ data ][ cards ]
content_list = []
for card in cards:
content_data = {}
content_data[ title_top ] = title_top
content_data[ crawl_time ] = int(time.time()) # 爬取的时间戳
content_data[ weibo_url ] = card[ scheme ] # 微博url
content = card[ mblog ]
content_data[ user_id ] = content[ user ][ id ] # 用户id
user_name = content[ user ][ screen_name ]
content_data[ weibo_id ] = content[ bid ]
content_data[ user_name ] = user_name # 用户名
content_data[ user_info ] = content[ user ] # 博主信息
if created_at in content:
content_data[ create_at ] = content[ created_at ] # 微博创建时间
content_data[ like_num ] = content[ attitudes_count ] # 点赞数
content_data[ repost_num ] = content[ reposts_count ] # 转发数
content_data[ comment_num ] = content[ comments_count ] # 评论数
content_data[ source ] = content[ source ] # 微博来源
## 微博内容
content_data[ content ] = content[ text ] # 微博内容
content_data[ content ] = re.sub(r <.*?> , ,content_data[ content ])
if page_info in content:
page_info = content[ page_info ]
if title in page_info:
content_data[ video_title ] = page_info[ title ] # 视频或其他链接title
if page_title in page_info:
content_data[ page_title ] = page_info[ page_title ] # 视频或其他链接title
if media_info in page_info:
content_data[ video_url ] = page_info[ media_info ][ stream_url ] # 视频url
content_data[ play_count ] = page_info[ play_count ] # 视频播放次数
if url_ori in page_info:
content_data[ url_ori ] = page_info[ url_ori ] # 原微博
if pics in content:
content_data[ pic_type ] = 1 # 是否带图片
for p in content[ pics ]:
savePics(p[ url ], user_name, path = 自己的路径 )
content_list.append(content_data) ## 后面再生成DataFrame
其他注意事项
热门内容的爬取好像就结束了,其他注意事项就是可能有时候获取不到网页,可以自己设置个循环跟判断语句,再加上time.sleep()
指令,如果实在获取不到就跳过啦~
其他榜单内容爬取
其他榜单的具体内容跟热门内容基本一致,所以具体内容就不赘述了。
主要区别一方面是接口,同样点进移动端(https://m.weibo.cn),其他榜单的数据放在带有trendtop
字样的文件里,列如榜单的链接就是
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_8999_-_ctg1_8999_home
这里把自己用的几个榜单放上来
urls = [
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_8999_-_ctg1_8999_home , ## 榜单
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_2088_-_ctg1_2088 , ## 科技
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_4288_-_ctg1_4288 , ## 明星
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_3288_-_ctg1_3288 , ## 电影
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_5288_-_ctg1_5288 , ## 音乐
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_1988_-_ctg1_1988 , ## 情感
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_4488_-_ctg1_4488 , ## 时尚
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_1588_-_ctg1_1588 , ## 美妆
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_4888_-_ctg1_4888 , ## 游戏
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_5188_-_ctg1_5188 , ## 数码
]
第二个区别是翻页的字段,其他榜单用的是page
字段不是since_id
,且直接在data
层就可以找到
第三个区别是数据存储的位置,其他榜单的博文内容存储在data
中的statuses
。
这篇结束了!
以上为微博热门内容、榜单的博文爬取详解,其他之后再写啦~
有参考到其他文章的地方我也忘了,总之搜索再加上自己摸索吧。不过微博还是存在许多限制的,许多东西也爬不全。
爬取热门微博这些要注意去重,里面会有许多内容是重复的,由于翻页存在一些停滞之类的吧~
- 最新
- 最热
只看作者