环境介绍
Python3.6.2/Windows-7-64位/微博移动端
实现目标
将微博上你感兴趣的博主微博(全部或过滤非原创等)内容获取,包括微博文本、图片和热评,文本和热评按编号存入txt文件中,图片按编号存入指定路径文件夹中。这样一来方便对你关注的微博信息进行定期保存以及后期的检索查阅,二来将这些数据获取后也可以对博主微博、评论等信息进行进一步的数据分析。
本例中获取数据保存在本地文件系统,如爬取数据量大,可考虑使用MongoDB等数据库,方便数据存储和检索查阅。
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
准备工作
一般来说同一网站,PC站的信息较为全面,但不易爬取,而移动端则相对来说比较简单,因此本例中选取移动端站点m.weibo.com作为入口来进行爬取。
进入所要爬取的博主的主页,以我关注的“博物杂志”为例,发现其主页url为:
https://m.weibo.cn/u/1195054531?uid=1195054531&luicode=10000011&lfid=100103type%3D1%26q%3D%E5%8D%9A%E7%89%A9%E6%9D%82%E5%BF%97
其中1195054531这段数字就是我们要找的uid,然后打开在浏览器中输入url: m.weibo.cn/u/1195054531 再次进入相同主页,这时候按F12打开谷歌开发者工具,点“Network”,因为移动端站点加载方式为异步加载,我们主要关注XHR下请求,点“XHR”,按F5刷新重新发送请求。这时候发现浏览器已经发送两个请求,第一个请求主要是为了获取一些和博主相关的介绍信息,而第二个请求就是为了获取第一页所有微博的信息,我们重点关注第二个请求。
点“Headers”,可以发现Request URL 、Cookie、Referer等我们需要的信息(Cookie信息这里采用手动获取方式,有效时间为几个小时不等,过期后需要手动重新获取一下), 其中Request URL为
https://m.weibo.cn/api/container/getIndex?type=uid&value=1195054531&containerid=1076031195054531
后面通过观察发现,在这个url末尾加上&page=页数可以控制想要爬取的微博页数。 点“Preview”:
观察返回的json数据,cards下就是一条条微博的信息card。 点开mblog,可以获取详细的微博相关内容:
我们主要需要以下数据: ‘id’:微博编号 ‘text’:微博文本 ‘islongText’:判断该条微博是否为长微博 ‘bmiddle_pic’:判断该微博是否带有图片
点开某条具体微博,来到微博完整内容和评论页面,同理通过观察“Network中请求相关信息,可以发现该页面url为: https://m.weibo.cn/api/comments/show?id=3900009063730800&page=1
其中id后面数字即为我们前面获取的微博编号,page参数可控制微博页数,请求返回json格式数据如下:
其中’data’和’hotdata’分别为评论和热评数据。
实现逻辑
- 通过控制page参数获取每页微博的cards数据,其中包含各条微博的详细信息;
- 开始遍历每一页微博页,同时遍历每一页的每一个微博,期间进行如下操作:
- 判断是否为长微博,如不是获取文本信息,否则进入详细微博内容请求,获取文本信息,将文本信息写入txt文档;
- 判断微博是否带有图片,如有通过请求获取图片地址,遍历地址,将其链接写入txt文档,将图片保存到本地,如无图片结束;
- 通过微博评论请求,获取评论数据列表,遍历列表获得该微博下每一条评论并保存到txt文档中相应微博内容下; …… 直到遍历完每一条微博。
爬取过程
爬取结果
文件夹中为对应微博图片,txt文档中为爬取的微博文本、评论内容。
以爬取“博物杂志”第3条微博为例,原博内容如下:
Txt文本中微博文本和评论如下:
文件夹中对应图片如下:
相对来说可以比较方便地进行检索和查阅。
代码实现
from lxmlimport html
import requests
import json
import re
import os
import time
import urllib.request
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
class CrawlWeibo:
# 获取指定博主的所有微博cards的list
defgetCards(self, id, page): # id(字符串类型):博主的用户id;page(整型):微博翻页参数
ii = 0
list_cards = []
while ii < page:
ii = ii + 1
print('正在爬取第%d页cards' % ii)
url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value=' + id + '&containerid=107603' + id + '&page=' + str(
ii)
response = requests.get(url, headers=headers)
ob_json = json.loads(response.text) # ob_json为dict类型
list_cards.append(ob_json['data']['cards']) # ob_json['data']['cards']为list类型
time.sleep(2)
print('暂停2秒') # 爬完一页所有微博的cards后 停顿两秒
return list_cards# 返回所有页的cards