近期的项目中使用了Jsoup来解析网页,下面就给大家(特别是新手)献丑讲下如何使用Jsoup来解析网页内容。首先看下我们在实际使用中加载网页常用的WebView的表现如何
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.WebView; public class Main2Activity extends AppCompatActivity { WebView webView ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); webView = (WebView) this.findViewById(R.id.web); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setBlockNetworkImage(true); webView.loadUrl("https://www.csdn.net/"); } }这里是加载CSDN的首页,看下模拟器上效果如何
效果还是杠杠滴,这个说明CSDN对手机的适配和支持做的还是挺不错的,但不是每个网页都这样做了很好的处理,比如下面的页面
两厢对比之下,发现webview也有其局限性,如果加载的网页没有做合适的手机适配,那么就无法在移动端展示更好,而且文字图片无法自定义显示,为了改变这样的不足,我们就需要拿到网页源码,自己进行解析和显示,而在这个过程中Jsoup可以帮我们的大忙,下面看下如何使用jsoup。
首先在gradle中引入依赖
compile 'org.jsoup:jsoup:1.9.2'
下面看下.java如何编写的
public class MainActivity extends AppCompatActivity { private TextView content ; private static String URL = "https://www.csdn.net/" ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); content = (TextView) this.findViewById(R.id.tv_content); // 由于加载的文字内容可能比较多,这里让文本框显示内容可以上下滑动 content.setMovementMethod(ScrollingMovementMethod.getInstance()); // 新开一个线程来加载网页资源 new Thread(new Runnable() { @Override public void run() { try { Document document = Jsoup.connect(URL).get(); Message msg = new Message(); msg.what = 100 ; msg.obj = document.outerHtml(); handler.sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } } }).start(); } public Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 100){ content.setText((String)msg.obj); } } }; }
可以看到,拿到了所有网页源码文件,如果稍微有点前端知识,那么接下来的工作就是根据标签来一个个解析进行显示了。下面拿博主的一篇文章举例子,
例如在这个页面,我只需要关注博文的正文部分,对于头部,左侧,底部以及广告部分都不想显示在手机页面上,那么就需要我们自己进行解析了。
对比了一下,发现页面上请求的标签和手机请求后解析的标签还是有点差别,所以果断选择手机请求的源码标签进行解析,否则会解析不出来内容。看下修改后的源码
public class MainActivity extends AppCompatActivity { private TextView content ; // private static String URL = "https://www.csdn.net/" ; private static String URL = "http://blog.csdn.net/u010898329/article/details/75005814" ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); content = (TextView) this.findViewById(R.id.tv_content); // 由于加载的文字内容可能比较多,这里让文本框显示内容可以上下滑动 content.setMovementMethod(ScrollingMovementMethod.getInstance()); // 新开一个线程来加载网页资源 new Thread(new Runnable() { @Override public void run() { try { Document document = Jsoup.connect(URL).get(); Message msg = new Message(); msg.what = 100 ; msg.obj = document.body(); Log.d("CJT" , "999999999999----"+document.body().outerHtml()); // Log.d("CJT" , "999999999999----"+document.body().getElementsByClass("blog_article_c").outerHtml()); handler.sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } } }).start(); } public Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 100){ Elements elements = ((Element)msg.obj).getElementsByClass("blog_article_c"); content.setText(Html.fromHtml(elements.outerHtml())); } } }; }
直接把原来页面上所有的body标签下的内容都传入handler,然后在handler中通过jsoup的getElementsByClass方法就可以获取到class内容了,解析后显示在页面上,除了这个方法,还有很多的get方法大家可以自行探索,看下解析显示的效果。
还是不错的,至少拿到了我们想要的内容,这里我是用ScrollView包裹TextView进行显示的,如果有需要,界面可以进一步美化,例如文章标题,发表时间,正文内容等都可以单独列出来,这样做的可控性比WebView好多了,至少广告和标题头都看不见了,算是网络爬虫的基本雏形了,有兴趣各位可以下去深入研究。
这里还有一个问题,就是文章中有图片没有显示出来,那么应该怎么处理呢?下一篇中跟大家分享这个技术点。