微博移动端所获数据各字段的含义

来源:互联网 发布:cloudlink mac客户端 编辑:程序博客网 时间:2024/06/05 22:39

最近在写微博的爬虫,框架已经基本稳定,但是在解析各字段含义的环节卡了好几天,因为不清楚各个字段的含义,官网的api注释好像有点过时,很多字段没有注释,所以只能自己一点一点分析了

现在把我自己分析得到的各字段含义分享一下,不能保证完全正确,但是大致无误

移动端得到的微博数据是json格式的,获得一个页面的数据以后,设为data,则
data[‘cards’][0][‘card_group’]
能够获得一个数组,数组内每个元素都是一行微博,里面包含了发布时间,微博内容,发布用户,转载内容等等。具体的字段有:

'idstr',                    #等同于id,是str形式'id',                       #信息id'created_timestamp',        #创建时间戳 ex:1448617509'created_at',               #创建时间。但是要注意,如果是今年以前的数据,                            #显示格式是'year-month-day hour:min:sec' 格式。                            #而今年的数据则显示为'month-day hour:min:sec'格式'attitudes_count',          #点赞数'reposts_count',            #转发数'comments_count',           #评论数目'isLongText',               #是否是长微博(就目前来看,都是False)'source',                   #用户客户端(iphone等)'pid',                      #不明,但是有必要保存,不一定有值'bid',                      #不明,但是有必要保存,不一定有值# 图片信息--------------------------------------------------------------'original_pic',             #图片相关,原始图片地址'bmiddle_pic',              #图片地址,与original_pic相比,只是把large换位bmiddle'thumbnail_pic',            #地址似乎等于pic中图片地址,尺寸是thumb'pic_ids',                  #图片id,是个Array'pics',                     #如果包含图的话,有该项,是一个数组,内嵌字典,                            # 包括size,pid,geo,url等# 以下字段内含数组或字典格式,需要进一步处理----------------------------------'retweeted_status',         #转载信息。如果该微博内有转载信息,则含有该项。转载项字段与本微博一致'user',                     #用户信息,字典格式。其中['uid']与['name']分别表示用户的id和名字'page_info',                #页面内嵌的链接的信息。比如外链,文章,视频,地理信息专题等内容。'topic_struct',             #话题信息,是数组格式,内涵字典,其中有'topic_title'项。'text',                     #文本信息。内涵表情,外链,回复,图像,话题等信息。

这里要讲一下text项的处理问题。由于text项其实是一段html代码,所以也可以用网页分析包(如python的beautifulsoup, java 的 jsoup 等)来分析,但是一则没有必要且速度慢,二则在新的云主机上配置客户端的时候还要下依赖包很麻烦,所以就使用正则表达式来分析了

随便调了一个文本过来,是这样的

<a class="k" href="/k/%E9%9F%B3%E4%B9%90%E4%B8%8B%E5%8D%88%E8%8C%B6?from=feed">#音乐下午茶#</a>未觉池塘春草梦,阶前梧叶已秋声。雨侵坏瓮新苔绿,秋入横林数叶红。夜深风竹敲秋韵,万叶千声皆是恨。人人解说悲秋事,不似诗人彻底知...<a data url=http://t.cn/zRMpLeo href="http://weibo.cn/sinaurl?u=http%3A%2F%2Ft.cn%2FzRMpLeo%3Furl_type%3D1%26object_type%3D%26pos%3D1&ep=AfF1y1cpN%2C2590506210%2CAfF1y1cpN%2C2590506210" class=""><i class="iconimg iconimg-xs"><img src="http://u1.sinaimg.cn/upload/2014/10/16/timeline_card_small_video_default.png"></i><span class="surl-text">视频</span></a>

在上述文本中,包含了一个topic链接(#音乐下午茶#),一个外链链接(视频)还有文本(未觉池塘春草梦,阶前梧叶已秋声。雨侵坏瓮新苔绿,秋入横林数叶红。夜深风竹敲秋韵,万叶千声皆是恨。人人解说悲秋事,不似诗人彻底知…)

各项相对于的正则表达式如下所示

<i.+?</i>           #表情,也可能内含一些东西<a class="k".+?</a> #话题         <a href.+?</a>      #用户链接               回复.+?//            #回复              \[.+?\]             #表情             <a data-url.+?</a>  #一般表示外链,表示视频,网页等等<img.+?>            #图像

下面是相对应的python代码,都包含在parseMicroblogPage类中。当获得页面数据之后,调用其中的parse_blog_page函数,即会返回一个数组,里面包含了处理过以后的微博数据

class parseMicroblogPage():    def __init__(self):        self.p_face=re.compile(r'\[.+?\]')        self.p_face_i=re.compile(r'<i.+?</i>')        self.p_user=re.compile(r'<a href.+?</a>')        self.p_topic=re.compile(r'<a class="k".+?</a>')        self.p_reply=re.compile(r'回复.+?//')        self.p_link=re.compile(r'<a data-url.+?</a>')        self.p_img=re.compile(r'<img.+?>')        self.p_span=re.compile(r'<span.+?</span>')        self.p_http_png=re.compile(r'http://.+?png')    def parse_blog_page(self,data):        try:        # check if the page is json type            data=json.loads(data)        except:            save_page(data)            raise ValueError('Unable to parse page')        try:        # check if the page is empty            mod_type=data['cards'][0]['mod_type']        except:            save_page(json.dumps(data))            raise ValueError('The type of this page is incorrect')        if 'empty' in mod_type:            raise ValueError('This page is empty')        try:        # get card group as new data            data=data['cards'][0]['card_group']        except:            save_page(json.dumps(data))            raise ValueError('The type of this page is incorrect')        data_list=[]        for block in data:            res=self.parse_card_group(block)            data_list.append(res)        return data_list    def parse_card_group(self,data):        data=data['mblog']        msg=self.parse_card_inner(data)        return msg    def parse_card_inner(self,data):        msg={}        keys=list(data.keys())        key_array=[            # 基本信息--------------------------------------------------------------            'idstr',                        #等同于id,是str形式            'id',                           #信息id            'created_timestamp',          #创建时间戳 ex:1448617509            'attitudes_count',            #点赞数            'reposts_count',              #转发数            'comments_count',             #评论数目            'isLongText',                  #是否是长微博(就目前来看,都是False)            'source',                      #用户客户端(iphone等)            'pid',                         #不明,但是有必要保存,不一定有值            'bid',                         #不明,但是有必要保存,不一定有值            # 图片信息--------------------------------------------------------------            'original_pic',               #图片相关,原始图片地址            'bmiddle_pic',                #图片地址,与original_pic相比,只是把large换位bmiddle            'thumbnail_pic',              #地址似乎等于pic中图片地址,尺寸是thumb            'pic_ids',                     #图片id,是个Array            'pics',                        #如果包含图的话,有该项,是一个数组,内嵌字典,                                            # 包括size,pid,geo,url等        ]        for item in keys:            if item in key_array:                msg[item]=data[item]        #糅合 id , mid , msg_id        if 'id' not in keys:            if 'mid' in keys:                msg['id']=data['mid']            elif 'msg_id' in keys:                msg['id']=data['msg_id']        if 'attitudes_count' not in keys and 'like_count' in keys:            msg['attitudes_count']=data['like_count']        # created_at        if 'created_at' in keys:            if data['created_at'].__len__()>14:                msg['created_at']=data['created_at']            else:                if 'created_timestamp' in keys:                    stamp=data['created_timestamp']                    x=time.localtime(stamp)                    str_time=time.strftime('%Y-%m-%d %H:%M',x)                    msg['created_at']=str_time                else:                    msg['created_at']=config.CURRENT_YEAR+'-'+data['created_at']        # retweeted_status        if 'retweeted_status' in keys:            msg['retweeted_status']=self.parse_card_inner(data['retweeted_status'])            msg['is_retweeted']=True        else:            msg['is_retweeted']=False        # user        if 'user' in keys:            msg['user']=self.parse_user_info(data['user'])            msg['user_id']=msg['user']['uid']            msg['user_name']=msg['user']['name']        # url_struct        # msg['url_struct']=self.parse_url_struct(data['url_struct'])        # page_info        if 'page_info' in keys:            msg['page_info']=self.parse_page_info(data['page_info'])        # topic_struct        if 'topic_struct' in keys:            msg['topic_struct']=self.parse_topic_struct(data['topic_struct'])        # text        if 'text' in keys:            msg['ori_text']=data['text']            msg['dealed_text']=self.parse_text(data['text'])        return msg    def parse_user_info(self,user_data):        keys=user_data.keys()        user={}        if 'id' in keys:            user['uid']=str(user_data['id'])        if 'screen_name' in keys:            user['name']=user_data['screen_name']        if 'description' in keys:            user['description']=user_data['description']        if 'fansNum' in keys:            temp=user_data['fansNum']            if isinstance(temp,str):                temp=int(temp.replace('万','0000'))            user['fans_num']=temp        if 'gender' in keys:            if user_data['gender']=='m':                user['gender']='male'            if user_data['gender']=='f':                user['gender']='female'        if 'profile_url' in keys:            user['basic_page']='http://m.weibo.cn'+user_data['profile_url']        if 'verified' in keys:            user['verified']=user_data['verified']        if 'verified_reason' in keys:            user['verified_reason']=user_data['verified_reason']        if 'statuses_count' in keys:            temp=user_data['statuses_count']            if isinstance(temp,str):                temp=int(temp.replace('万','0000'))            user['blog_num']=temp        return user    def parse_text(self,text):        msg={}        # data-url        data_url=re.findall(self.p_link,text)        if data_url.__len__()>0:            data_url_list=[]            for block in data_url:                temp=self.parse_text_data_url(block)                data_url_list.append(temp)            msg['data_url']=data_url_list        text=re.sub(self.p_link,'',text)        # topic        topic=re.findall(self.p_topic,text)        if topic.__len__()>0:            topic_list=[]            for block in topic:                temp=self.parse_text_topic(block)                topic_list.append(temp)            msg['topic']=topic_list        text=re.sub(self.p_topic,'',text)        # moiton        motion=[]        res1=re.findall(self.p_face_i,text)        for item in res1:            temp=re.findall(self.p_face,item)[0]            motion.append(temp)        text=re.sub(self.p_face_i,'',text)        res2=re.findall(self.p_face,text)        motion=motion+res2        if motion.__len__()>0:            msg['motion']=motion        text=re.sub(self.p_face,'',text)        # user        user=[]        user_res=re.findall(self.p_user,text)        if user_res.__len__()>0:            for item in user_res:                temp=self.parse_text_user(item)                user.append(temp)            msg['user']=user        text=re.sub(self.p_user,'@',text)        msg['left_content']=text.split('//')        return msg    def parse_text_data_url(self,text):        link_data={}        link_data['type']='data_url'        try:            res_face=re.findall(self.p_face_i,text)[0]            res_img=re.findall(self.p_img,res_face)[0]            res_http=re.findall(self.p_http_png,res_img)[0]            link_data['img']=res_http            res_class=re.findall(r'<i.+?>',text)[0]            link_data['class']=res_class            text=re.sub(self.p_face_i,'',text)        except:            pass        try:            res_span=re.findall(self.p_span,text)[0]            title=re.findall(r'>.+?<',res_span)[0][1:-1]            link_data['title']=title            text=re.sub(self.p_span,'',text)        except:            pass        try:            data_url=re.findall(r'data-url=".+?"',text)[0]            data_url=re.findall(r'".+?"',data_url)[0][1:-1]            link_data['short_url']=data_url            url=re.findall(r'href=".+?"',text)[0][6:-1]            link_data['url']=url        except:            pass        # print(text)        # print(json.dumps(link_data,indent=4))        return link_data    def parse_text_topic(self,text):        data={}        try:            data['type']='topic'            data['class']=re.findall(r'class=".+?"',text)[0][7:-1]            data['title']=re.findall(r'>.+?<',text)[0][1:-1]            data['url']='http://m.weibo.cn'+re.findall(r'href=".+?"',text)[0][6:-1]        except:            pass        return data    def parse_text_user(self,text):        data={}        data['type']='user'        try:            data['title']=re.findall(r'>.+?<',text)[0][2:-1]            data['url']= 'http://m.weibo.cn'+re.findall(r'href=".+?"',text)[0][6:-1]        except:            pass        return data    def parse_url_struct(self,data):        url_struct=[]        for block in data:            keys=block.keys()            new_block=block            url_struct.append(new_block)        return url_struct    def parse_page_info(self,data):        keys=data.keys()        key_array=[            'page_url',            'page_id',            'content2',            'tips',            'page_pic',            'page_desc',            'object_type',            'page_title',            'content1',            'type',            'object_id'        ]        msg={}        for item in keys:            if item in key_array:                msg[item]=data[item]        return msg    def parse_topic_struct(self,data):        msg=[]        for block in data:            keys=block.keys()            temp=block            if 'topic_title' in keys:                temp['topic_url']='http://m.weibo.cn/k/{topic}?from=feed'\                    .format(topic=block['topic_title'])            msg.append(temp)        return msg
0 0
原创粉丝点击