安卓课程设计-新闻客户端(基于网页抓取)_第1页
安卓课程设计-新闻客户端(基于网页抓取)_第2页
安卓课程设计-新闻客户端(基于网页抓取)_第3页
安卓课程设计-新闻客户端(基于网页抓取)_第4页
安卓课程设计-新闻客户端(基于网页抓取)_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

题目android课程设计——新闻客户端姓名:学号:专业:学院:指导教师:二零一八年十一月一、需求分析启动程序后可以进行新闻资讯的实时更新,可分不同的栏目让使用者了解任意感兴趣的资讯进行阅读,启动程序后可以进行新闻资讯的实时更新,可分不同的栏目让使用者了解任意感兴趣的资讯进行阅读。1)启动应用程序;2)设置界面:采用多种布局嵌套,美化控件。3)显示界面:模仿网易新闻客户端进行UI编写。4)详细界面:分为头条、国内、国际、财经、科技、社会等板块从用户的角度出发,针对用户的需求,所涉及的程序响应速度快、信息处理速度快、平安性高是用户所需要的三大主要性能,另外为了受众面更广,根据目前的android设备系统版本的分布情况,android2.3以上的版本占到设备总量的80%以上,所以做开发的时候选择的android系统最低版本也必须是android2.3以上来保证用户量。二、概要设计〔一〕开发环境采用windows+Eclipse+ADT的环境进行开发,在Android2.3以上版本的系统中运行的。〔二〕系统流程软件分为了两大模块,分别是新闻客户端模块和效劳器模块。a〕客户端顾名思义就是前台框架设计,模仿了网易新闻的app,界面设计参考的是github网站的前辈;备注:翻开后界面默认为“头条〞界面b〕效劳器这里值得一提的是做成了抓取各新闻网站,解析出新闻呈现给前台,用的是jsoup.jar获取和htmlparser.jar解析,有点复杂了,但还好有使用方法,能直接拿过来用。1.jsoup.jar获取〔参考:〕将下载下来的jar包放到放到Android工程中libs目录下,加以编写即可:Stringhtml="<html><head><title>Firstparse</title></head>"+"<body><p>ParsedHTMLintoadoc.</p></body></html>";Documentdoc=Jsoup.parse(html);上面这个例子比拟简单,直接就将html转换成Document实例了,之后再解析2.htmlparser.jar解析〔参考:〕网页解析模块要实现两大功能:1.从页面中提取出子链接,参加到爬取url队列中;2.解析网页内容,与主题进行相关度计算。具体步骤如下:a.读取html文件,获得页面编码,获得String格式的文件内容b.用页面编码实例化html文件的Parserc.对需要提取的结点设置相应的Filterd.根据给定的Filter,用Parser解析html文件e.提取结点中的文本内容,进行处理三、设计与实现〔一〕布局设计主要设计了三个界面:全局界面、新闻列表显示界面、详细新闻界面a.全局界面〔main.xml〕<?xmlversion="1.0"encoding="utf-8"?>android"xmlns:tools="://schemas.android/tools"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="@drawable/bg_title_bar"android:orientation="vertical"tools:context=".Main"><LinearLayoutandroid:id="@+id/title_layout"android:layout_width="fill_parent"android:layout_height="20dp"android:background="@drawable/public_titlebar_bg"android:orientation="horizontal"><TextViewandroid:id="@+id/textView_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="@string/app_name"android:textColor="#000"android:textSize="12sp"/></LinearLayout><LinearLayoutandroid:id="@+id/main_type_title"android:layout_width="wrap_content"android:layout_height="50dip"android:layout_gravity="center_vertical"android:orientation="horizontal"><HorizontalScrollViewandroid:id="@+id/main_scroll"android:layout_width="0dip"android:layout_height="50dip"android:layout_weight="1"android:scrollbars="none"><LinearLayoutandroid:id="@+id/main_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:orientation="horizontal"></LinearLayout></HorizontalScrollView><Buttonandroid:id="@+id/main_speak"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="10dip"android:layout_marginRight="10dip"android:background="@drawable/bg_read_button_select"android:gravity="right|center_vertical"android:paddingRight="10dip"android:text="@string/button_text_read"android:textColor="#FFFFFFFF"/></LinearLayout>android:id="@+id/main_page"android:layout_width="wrap_content"android:layout_height="0dp"android:layout_weight="1"android:background="#FF000000"/></LinearLayout>b.新闻列表显示界面(list_item.xml)ListView是Android系统自带的控件之一,它的使用同样是十分广泛的,它通常用来加载一系列相同布局的列表。使用它同样需要一个PagerAdapter适配器来给它提供数据。从新闻列表的特征来看,显然是由一个ListView来实现的。但是为了在滑动ListView的时候,带动ViewPager一起滑动,那么需要自定义一个控件,来讲广告轮播条的ViewPager和新闻列表的ListView关联起来。而大局部的新闻软件都有上拉刷新和下拉加载更多的功能,所以在此自定义控件中也应加上上拉刷新和下拉加载更多的功能。此自定义控件继承了ListView类,实现了OnScrollListener,android.widget.AdapterView.OnItemClickListener接口。c.详细新闻界面(detail.xml)新闻详情页即是点击新闻进入后的页面,使用一个ScrollView来实现。在新闻详情页中,用户可以点击返回按钮返回到前一页面。〔二〕功能实现a.主新闻页面的设计与实现定义出页面所需要用到的控件以及新闻栏目的适配器〔如右图〕,然后初始化界面布局、标题等:protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); initLayout(); initViewPage(); initTitle(); }b.新闻详细页面的设计与实现:c.数据接口:publicclassDataAdapterextendsBaseAdapter{ ContextmContext=null; LayoutInflaterinflater; List<NewsBrief>newsData=newArrayList<NewsBrief>(); publicDataAdapter(Contextcontext,List<NewsBrief>nList){ mContext=context; inflater=LayoutInflater.from(context); newsData=nList; } @Override publicintgetCount(){ returnnewsData.size(); } @Override publicObjectgetItem(intarg0){ returnnull; } @Override publiclonggetItemId(intposition){ return0; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupparent){ HolderViewhView=null; if(null==convertView){ hView=newHolderView(); convertView=inflater.inflate(R.layout.list_item,null); hView.image=(ImageView)convertView.findViewById(R.id.news_image); hView.speak=(ImageView)convertView.findViewById(R.id.news_speak); hView.title=(TextView)convertView.findViewById(R.id.news_title); hView.brief=(TextView)convertView.findViewById(R.id.news_brief); hView.where=(TextView)convertView.findViewById(R.id.news_where); hView.date=(TextView)convertView.findViewById(R.id.news_time); convertView.setTag(hView); }else{ hView=(HolderView)convertView.getTag(); } hView.title.setText(newsData.get(position).getTitle()); if(!"".equals(newsData.get(position).getContent())&&newsData.get(position).getContent().length()>26){ Stringstr=newsData.get(position).getContent().trim().substring(0,24); hView.brief.setText(NetUtil2.replaceBlank(str)); }else{ hView.brief.setText(""); } if(NetUtil2.CURRENT_SPEAK.equals(newsData.get(position).getUrl())){ hView.speak.setVisibility(View.VISIBLE); hView.title.setTextColor(Color.RED); }else{ hView.speak.setVisibility(View.GONE); hView.title.setTextColor(Color.WHITE); } hView.where.setText(newsData.get(position).getSource()); hView.date.setText(newsData.get(position).getPubDate()); if(null!=newsData.get(position).getImgUrl() &&!"".equals(newsData.get(position).getImgUrl())){ hView.image.setTag(newsData.get(position).getImgUrl()); ImageLoader2.getInstance(mContext).loadImage(newsData.get(position).getImgUrl(),hView.image); }else{ hView.image.setImageResource(R.drawable.icon_image_default); } returnconvertView; } publicclassHolderView{ privateImageViewimage=null; privateImageViewspeak=null; privateTextViewtitle=null; privateTextViewbrief=null; privateTextViewwhere=null; privateTextViewdate=null; }}d.数据获取:利用jsoup和htmlparser抓紧并解析新闻,下面为解析腾讯新闻页面:publicclassNetUtil{publicstaticList<NewsBrief>DATALIST=newArrayList<NewsBrief>();publicstaticString[][]CHANNEL_URL=newString[][]{newString[]{"://news.qq/world_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/society_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},newString[]{"://news.qq/china_index.shtml","://news.qq"},};publicstaticintgetTechNews(List<NewsBrief>techData,intcId){intresult=0;try{NodeFilterfilter=newAndFilter(newTagNameFilter("div"),newHasAttributeFilter("id","listZone"));Parserparser=newParser();parser.setURL(CHANNEL_URL[cId][0]);parser.setEncoding(parser.getEncoding());NodeListlist=parser.extractAllNodesThatMatch(filter);for(inti=0;i<list.size();i++){Tagnode=(Tag)list.elementAt(i);for(intj=0;j<node.getChildren().size();j++){try{Stringtextstr=node.getChildren().elementAt(j).toHtml();if(textstr.trim().length()>0){NodeFiltersubFilter=newTagNameFilter("p");ParsersubParser=newParser();subParser.setResource(textstr);NodeListsubList=subParser.extractAllNodesThatMatch(subFilter);NodeFiltertitleStrFilter=newAndFilter(newTagNameFilter("a"),newHasAttributeFilter("class","linkto"));ParsertitleStrParser=newParser();titleStrParser.setResource(textstr);NodeListtitleStrList=titleStrParser.extractAllNodesThatMatch(titleStrFilter);intlinkstart=titleStrList.toHtml().indexOf("href=\"");intlinkend=titleStrList.toHtml().indexOf("\">");inttitleend=titleStrList.toHtml().indexOf("</a>");Stringlink=CHANNEL_URL[cId][1]+titleStrList.toHtml().substring(linkstart+6,linkend);Stringtitle=titleStrList.toHtml().substring(linkend+2,titleend);NewsBriefnewsBrief=newNewsBrief();newsBrief.setTitle(title);newsBrief.setUrl(link);newsBrief.setSummary(subList.asString());techData.add(newsBrief);}}catch(Exceptione){e.printStackTrace();}}}}catch(Exceptione){result=1;e.printStackTrace();}returnresult;}publicstaticintgetTechNews2(List<NewsBrief>techData,intcId){intresult=0;try{//查询://tech.qq/tech_yejie.htm页面滚动新闻的标签以及IDNodeFilterfilter=newAndFilter(newTagNameFilter("div"),newHasAttributeFilter("id","listZone"));Parserparser=newParser();parser.setURL(CHANNEL_URL[cId][0]);parser.setEncoding(parser.getEncoding());//获取匹配的fileter的节点NodeListlist=parser.extractAllNodesThatMatch(filter);StringBuilderNewsStr=newStringBuilder("<table>");//新闻表格字符串for(inti=0;i<list.size();i++){Tagnode=(Tag)list.elementAt(i);for(intj=0;j<node.getChildren().size();j++){Stringtextstr=node.getChildren().elementAt(j).toHtml().trim();if(textstr.length()>0){intlinkbegin=0,linkend=0,titlebegin=0,titleend=0;while(true){linkbegin=textstr.indexOf("href=",titleend);//截取链接字符串起始位置//如果不存在href了也就结束了if(linkbegin<0)break;linkend=textstr.indexOf("\">",linkbegin);//截取链接字符串结束位置Stringsublink=textstr.substring(linkbegin+6,linkend);Stringlink=CHANNEL_URL[cId][1]+sublink;titlebegin=textstr.indexOf("\">",linkend);titleend=textstr.indexOf("</a>",titlebegin);Stringtitle=textstr.substring(titlebegin+2,titleend);NewsStr.append("\r\n<tr>\r\n\t<td><atarget=\"_blank\"href=\""+link+"\">");NewsStr.append(title);NewsStr.append("</a></td></tr>");NewsBriefnewsBrief=newNewsBrief();newsBrief.setTitle(title);newsBrief.setUrl(link);techData.add(newsBrief);}}}}}catch(Exceptione){result=1;e.printStackTrace();}returnresult;}publicstaticintparserURL(Stringurl,NewsBriefnewsBrief){intresult=0;try{Parserparser=newParser(url);NodeFiltercontentFilter=newAndFilter(newTagNameFilter("div"),newHasAttributeFilter("id","Cnt-Main-Article-QQ"));NodeFilternewsdateFilter=newAndFilter(newTagNameFilter("span"),newHasAttributeFilter("class","article-time"));NodeFilternewsauthorFilter=newAndFilter(newTagNameFilter("span"),newHasAttributeFilter("class","color-a-1"));NodeFilterimgUrlFilter=newTagNameFilter("IMG");newsBrief.setContent(parserContent(contentFilter,parser));parser.reset();//记得每次用完parser后,要重置一次parser。要不然就得不到我们想要的内容了。newsBrief.setPubDate(parserDate(newsdateFilter,parser));parser.reset();newsBrief.setSource(parserAuthor(newsauthorFilter,parser));parser.reset();newsBrief.setImgUrl(parserImgUrl(contentFilter,imgUrlFilter,parser));}catch(Exceptione){result=1;e.printStackTrace();}returnresult;}privatestaticStringparserContent(NodeFilterfilter,Parserparser){Stringreslut="";try{NodeListcontentList=(NodeList)parser.parse(filter);//将DIV中的标签都去掉只留正文reslut=contentList.asString();}catch(Exceptione){e.printStackTrace();}returnreslut;}privatestaticStringparserDate(NodeFilterfilter,Parserparser){Stringreslut="";try{NodeListdatetList=(NodeList)parser.parse(filter);//将DIV中的标签都去掉只留正文reslut=datetList.asString();}catch(Exceptione){e.printStackTrace();}returnreslut;}privatestaticStringparserAuthor(NodeFilterfilter,Parserparser){Stringreslut="";try{NodeListauthorList=(NodeList)parser.parse(filter);//将DIV中的标签都去掉只留正文reslut=authorList.asString();}catch(Exceptione){e.printStackTrace();}returnreslut;}privatestaticList<String>parserImgUrl(NodeFilterbodyfilter,NodeFilterfilter,Parserparser){List<String>reslut=newArrayList<String>();try{NodeListbodyList=(NodeList)parser.parse(bodyf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论