微博移动端所获数据各字段的含义
来源:互联网 发布: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
- 微博移动端所获数据各字段的含义
- dba_segments各字段的含义
- trace文件各字段的含义
- iPhone CFSocketCreate的各字段含义
- 移动端meta标签的含义
- 屏幕字段结构SCREEN的字段含义
- “OEM”“RTM”“MSDN”各版本所代表的含义详解
- v$sql command_type各数字所代表的含义
- Ubuntu下输入ls -l 后各字段的含义
- Linux网卡设定网络参数各字段的含义
- 移动端meta几个值的设置以及含义
- access查询时字段太小而不能接受所要添加的数据的数量
- Linux下errno所代表的含义
- http状态码所代表的含义
- idea 文件名颜色所代表的含义
- HSV颜色所代表的含义
- bookstrap 样式所代表的含义
- 按某一字段分组取最大(小)值所在行的数据,如何按字段删除重复记录
- 资源释放 delete[]
- 在非越狱手机上进行App Hook
- ASP.NET WebForm Form表单如何实现MVC那种“自动装配”效果呢?
- newInstance() 和 new 有什么区别?
- 继续添加,确认删除,弹出对话框,跳转
- 微博移动端所获数据各字段的含义
- Android自带的时间空间和日期控件
- php输出各函数的区别
- java设计模式:动态代理模式 Proxy
- iOS开发系列--网络开发
- WebSocket
- mysql导入导出数据方法分享
- Formal System-谓词逻辑范式(Prädikatenlogik Normalformen)
- Spring Boot的日志管理