python爬取微博用户的微博内容和图片

想保存自己喜欢的idol微博图片,但是一张张自己保存太慢,怎么办?想保存微博博主的所有表情包,怎么才能快速把这些表情包下载到本地呢?想分析某位博主的发博规律,要分析博主所有微博信息怎么做?
python爬取微博用户的微博内容和图片
这就要用到爬虫啦,而写爬虫当然是用python啦,我们以移动端的刘亦菲微博作为实验,之所以用移动端的微博,是因为爬取难度比较低,网址为移动端微博,打开网站,搜索进入刘亦菲的微博,如下图所示。
python爬取微博用户的微博内容和图片
红圈圈的地方那一串数字就是刘亦菲微博的id啦,打开 Chrome 浏览器的调试功能,选择 Network 菜单,观察到获取微博数据的的接口是 https://m.weibo.cn/api/xxxxxxxxxx,点击进入 就得到返回数据的数据结构啦,如下图所示。
python爬取微博用户的微博内容和图片
但是这么密密麻麻的代码,谁才是我们想要的呢,难道要自己一个个去找吗?
python爬取微博用户的微博内容和图片
这里不要担心,我们一般需要的也就是微博文字、发表时间、赞评转数和微博图片啦,我制作了一份结构树状图,大家可以参考一下。
python爬取微博用户的微博内容和图片
首先呢,我们构建一个基本的请求头(因为不登录也可以获得微博内容,所以不需要cookie信息),构造请求头的代码如下。

host = 'm.weibo.cn'
base_url = 'https://%s/api/container/getIndex?' % host
user_agent = 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 wechatdevtools/0.7.0 MicroMessenger/6.3.9 Language/zh_CN webview/0'#这里的user_agent是网上找的

user_id = str(3261134763)#这串数字就是用户id
headers = {
    'Host': host,
    'Referer': 'https://m.weibo.cn/u/%s'%user_id,
    'User-Agent': user_agent
}

然后import要使用的模块

import requests
import urllib
import time
import os
import time_standard as tst
from tqdm import tqdm
from urllib.parse import urlencode
from pyquery import PyQuery as pq

其中time_standard模块是自己写的一个将微博created_at时间转换为标准的‘XXXX-XX-XX’形式的日期

import datetime
def timestr_standard(time_str):
    now_time = datetime.datetime.now()
    if time_str.endswith('分钟前') or time_str.endswith('小时前') or time_str == '刚刚':
        #strptime是把字符串转换为时间类。strftime是把时间转换为字符串
        time_standard = datetime.datetime.strftime(now_time.date(),'%Y-%m-%d')
    elif time_str.startswith('昨天'):
        time_standard = datetime.datetime.strftime((now_time - datetime.timedelta(days = 1)).date(),'%Y-%m-%d')
    elif time_str.startswith('0') or time_str.startswith('1'):
        time_standard = str(now_time.year) + '-' + time_str
    elif time_str.startswith('20'):
        time_standard = time_str
    return time_standard

构建好了请求头并且导入了模块就可以仿造请求得到 weibo 返回的数据了,这边构造一个请求函数。

def get_single_page(page):
    params = {
        'type': 'uid',
        'value': 1665372775,
        'containerid': int('107603' + user_id),#containerid就是微博用户id前面加上107603
        'page': page
    }
    url = base_url + urlencode(params)
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()
    except requests.ConnectionError as e:
        print('抓取错误', e.args)

得到返回的数据以后,还要对返回的数据进行解析,解析函数代码。

# 解析页面返回的json数据
def analysis_page(json,pic_filebagPath):#保存图片的文件夹路径
    items = json.get('data').get('cards')
    for item in items:
        item = item.get('mblog')
        if item:
            data = {
                'created_at': item.get('created_at'),#微博创建日期
                'text': pq(item.get("text")).text(),  # 仅提取内容中的文本
                'attitudes': item.get('attitudes_count'),#点赞数
                'comments': item.get('comments_count'),#评论数
                'reposts': item.get('reposts_count')#转发数
            }
            base_data[len(base_data)] = data#把得到的数据字典存入总字典
            if pic_choice == 'y':#如果选择保存图片
                pics = item.get('pics')
                if pics:
                    for pic in pics:
                        picture_url = pic.get('large').get('url')#得到原图地址
                        pid = pic.get('pid')#图片id
                        pic_name = tst.timestr_standard(data['created_at']) + '_' + pid[25:]#构建保存图片文件名,timestr_standard是一个把微博的created_at字符串转换为‘XXXX-XX-XX’形式日期的一个函数
                        download_pics(picture_url,pic_name,pic_filebagPath)#下载原图

下载图片的代码下所示。

def download_pics(pic_url,pic_name,pic_filebagPath): #pic_url大图地址,pic_name保存图片的文件名
    pic_filePath = pic_filebagPath + '\\'
    try:
        if pic_url.endswith('.jpg'):#保存jpg图片
            f = open(pic_filePath + str(pic_name)+".jpg", 'wb')
        if pic_url.endswith('.gif'):#保存gif图片
            f = open(pic_filePath + str(pic_name)+".gif", 'wb')
        f.write((urllib.request.urlopen(pic_url)).read())
        f.close()
    except Exception as e:
        print(pic_name+" error",e)
    time.sleep(0.1)#下载间隙

接下来就是总程序。

if __name__ == '__main__':
    base_data = {}
    page = input('请输入你要爬取的页数')#可输入爬取页数,或者输入‘all’爬取所有微博
    pic_choice = input('是否需要存储图片?y/n')#选择是否保存图片
    time_start=time.time()
    try:
        json = get_single_page(1)
        screen_name = json.get('data').get('cards')[0].get('mblog').get('user').get('screen_name')#博主昵称
        total = json.get('data').get('cardlistInfo').get('total')#博主微博总条数
        if pic_choice == 'y':#如果选择保存图片,则分配图片保存路径
            pic_filebagPath = 'D:\\python_project\\crawl\\weibo\\%s_picture'%screen_name
            os.makedirs(pic_filebagPath)#建立文件夹
        else:
            pic_filebagPath = None#选择不保存文件夹则不分配路径
        if page == 'all':#寻找总条数
            page = total//10
            while get_single_page(page).get('ok') == 1:
                page = page + 1
            print('总页数为:%s'%page)
        
        page = int(page) + 1
        for page in tqdm(range(1,page)):  # 抓取数据
            json = get_single_page(page)
            analysis_page(json,pic_filebagPath)
    except Exception as e:
        print('error:',e)
    finally:
        base_dataPath = 'D:\\python_project\\crawl\\weibo\\base_data_%s.txt'%screen_name#base_data保存地址和文件名
        f = open(base_dataPath,'w+',encoding='utf-8')
        f.write(str(base_data))
        f.close()
        time_end=time.time()
        print('\n totally cost',time_end-time_start)#显示程序运行时间

程序运行状态如下:
python爬取微博用户的微博内容和图片
经过一段时间的运行,就得到了所有的微博数据啦。
python爬取微博用户的微博内容和图片
得到的base_data字典数据。
python爬取微博用户的微博内容和图片
本次内容就是这样了,如果你觉得有帮助的话就点个赞吧!
python爬取微博用户的微博内容和图片