我相信很多写过新浪微博爬虫的朋友肯定都遇到过一个共同的问题,就是在解决新浪微博登陆之后如何解析新浪微博的源代码。其实新浪微博页面解析并不困难,然而初次接触的同学往往会被源代码页面给吓着而无从下手。例如下图所示(用户主页的用户主要信息所在源代码):
怎么样,看起来好像是挺吓人的吧,本文就解析用户信息页面为例,介绍如何进行新浪微博页面。通过本文的研究发现新浪微博大部分的页面结构类似。它都是有一个基本的html的骨干框架,然后具体的数据都是以上图的形式存在<script>脚本中。那么解决问题的第一步就是在页面的源代码中找到你所要提取信息所在的<script/>代码块。例如下面的代码表示如何得到相应代码块并将数据进行反序列化得到标准的html源码。
怎么样,看起来好像是挺吓人的吧,本文就解析用户信息页面为例,介绍如何进行新浪微博页面。通过本文的研究发现新浪微博大部分的页面结构类似。它都是有一个基本的html的骨干框架,然后具体的数据都是以上图的形式存在<script>脚本中。那么解决问题的第一步就是在页面的源代码中找到你所要提取信息所在的<script/>代码块。例如下面的代码表示如何得到相应代码块并将数据进行反序列化得到标准的html源码。
/**
* @param content
* 用户主页源代码
* @return mainContent 用户信息所在的html代码片段
* */
public String getMainContent(String content) {
String mainContent = "";
Document doc = Jsoup.parse(content);
Elements elements = doc.getElementsByTag("script");
Element element=null;
UserHomePage uHomePage =null;
for (int i = 0; i < elements.size(); ++i) {
element = elements.get(i);
if(element!=null)
if (element.data().startsWith("FM.view({\"ns\":\"pl.header.head.index\"")) {
mainContent = (String) element.data().substring(8,element.data().length() - 1);
uHomePage = JSON.parseObject(mainContent,UserHomePage.class);
mainContent = uHomePage.getHtml();
break;
}
}
return mainContent;
}
这里向大家强烈建议fastjson和jsoup两个工具,前者用于处理json格式数据,后者用于标准html tag树中数据的提取。那么解析页面的第二步就变得简单了,这里的数据解析也就是
通过匹配html的tag标签得到所需数据
。由于微博的企业用户和个人用户主页源码有所差异,在这里就个人用户主页的源码进行解析,如下面的代码所示:
<span style="font-size:10px;">/**
* 解析个人用户主页
* @param content
* @return
*/
public User prasePersonalUser(String content){
User user=new User();
Document doc=Jsoup.parse(content);
Element element=null;
Element pf_name=null;
Element pf_intro =null;
Element pf_tags=null;
Element pf_info_right=null;
Element user_atten=null;
Elements aElements=null;
if(doc!=null){
pf_name=doc.getElementsByAttributeValue("class", "pf_name bsp clearfix").first();
if(pf_name!=null){
element=pf_name.getElementsByAttributeValue("class", "name").first();
if(element!=null){
user.setName(element.text());//姓名
}
element=pf_name.getElementsByAttributeValueContaining("title", "当前等级").first();
if(element!=null){
int i= element.attr("title").indexOf(":");//中文分号
String level=element.attr("title").substring(i+1);
user.setLevel(Integer.parseInt(level));//设置用户等级
String id=element.attr("levelcard");
int index=id.indexOf("=");
id=id.substring(index+1);
user.setUid(id);//用户id
}
}
pf_intro = doc.getElementsByAttributeValue("class", "pf_intro bsp").first();
if (pf_intro != null) {
user.setDescription(pf_intro.text());//自我介绍
}
pf_tags=doc.getElementsByAttributeValue("class", "pf_tags bsp").first();
if (pf_tags != null) {
element =pf_tags.getElementsByAttributeValue("class", "layer_menulist_tags S_line3 S_bg5").first();
if(element !=null){
user.setTags(element .text());//设置用户标签
}
element =pf_tags.getElementsByAttributeValue("class", "tags").first();
if(element !=null){
aElements=element .getElementsByTag("a");
for(Element href:aElements){
if(href!=null&&href.attr("href").contains("loc=infgender")){
user.setGender(href.children().first().attr("title"));//性别
}
if(href!=null&&href.attr("href").contains("loc=infsign")){
user.setConstellation(href.text());//星座
}
if(href!=null&&href.attr("href").contains("loc=infplace")){
user.setLocation(href.text());//所在地
}
if(href!=null&&href.attr("href").contains("loc=infedu")){
user.setEdu(href.text());//教育
}
if(href!=null&&href.attr("href").contains("loc=infjob")){
user.setJob(href.text());//公司
}
}
}
}
pf_info_right = doc.getElementsByAttributeValue("class", "pf_info_right").first();
user.setVerified(false);
if (pf_info_right != null) {
element=pf_info_right.getElementsByAttributeValue("class", "pf_verified bsp").first();
if(element!=null){
user.setVerified(true);//是否为认证用户
}
}
user_atten=doc.getElementsByAttributeValueContaining("class", "user_atten clearfix").first();
if(user_atten!=null){
element=user_atten.getElementsByAttributeValueContaining("href", "mod=headfollow").first();
user.setFriendsCount(getCount(element));
element=user_atten.getElementsByAttributeValueContaining("href", "mod=headfans").first();
user.setFollowersCount(getCount(element));
element=user_atten.getElementsByAttributeValueContaining("href", "mod=headweibo").first();
user.setStatusesCount(getCount(element));
}
}
return user;
}</span>
好了,新浪微博用户信息提取就介绍到此。是不是非常简单!本文中所涉及到的用户界面解析完整源码见
UserHomePageParse