android 使用Jsoup 抓取页面的数据
来源:互联网 发布:哗啦啦餐饮软件好用吗 编辑:程序博客网 时间:2024/05/17 23:07
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
Jsoup的官方中文地址:http://www.open-open.com/jsoup/parse-document-from-string.htm
在这个网站上你可以找到一些说明,.jar文件的下载,doc文档的说明等等
jsoup的主要功能如下:
1. 从一个URL,文件或字符串中解析HTML;
2. 使用DOM或CSS选择器来查找、取出数据;
3. 可操作HTML元素、属性、文本;
jsoup是基于MIT协议发布的,可放心使用于商业项目。
Jsoup类下面的方法都是静态可直接调用。几个方法的说明
Connect()方法,获得一个Connection,然后调用Connection对象get()方法获得Document对象。然后再解析Document对象
Connection提供了一些设置方法timeout(),url()等等
Jsoup一些类的说明:
Document:extends Element。一个HTML文档。即你发送请求时,Server发给你的数据。同样也可以调用Element的方法。常用方法:
body(),head(),nodeName(),title(),title(String title)
Elements:获得的HTML的各个元素的集合。通过Element.select(String str)获取相应元素值
Element first():返回第一个匹配的元素,如果为空,则返回null
String text():返回所有匹配元素的混好text值
Element get(int index);
String attr(String attributeKey);
Element:HTML element由tag name, attributes, child nodes(including text nodes and other elements)。由Element,可以提取数据,理清节点图,操作HTML。
text(); 返回String类型
getElementsByClass(String class);
getAllElements(); 都返回Elements对象
getElementsByAttribute(String key);
Elements select(String selector); 根据匹配的selector选择相应的Elements
下面是一个纯java代码的例子,经测试可用:
- public static void main(String[] args) throws IOException {
- try {
- Document doc = Jsoup.connect("http://passover.blog.51cto.com/").get();
- System.out.println(doc.title());
- Elements eles = doc.select("div.artHead");
- System.out.println(eles.first().select("h3[class=artTitle]"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
// 对应网站代码html
div class="artHead"> <div><span class="artType01" style="margin-right: 5px;"><a href="javascript:void(0)">原创</a></span> <h3 class="artTitle"><a href="/2431658/1548232">Jenkins+Maven+Git搭建持续集成和自动化部署的配置手记</a> <a href="http://blog.51cto.com/artcommend" target="_blank"><img src="http://blog.51cto.com/image/skin/35/indextj.gif" width="15" height="15" /></a> </h3> </div>
注意:在运行的时候会出现下面这个错误: android.os.NetworkOnMainThreadException 这是因为Android4.0不支持在UI线程中访问网络。怕线程阻塞假死!有两个方法可以解决,一个是在主程序中增加:
// 详见StrictMode文档
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() // or .detectAll() for all detectable problems .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build());
另一种 是启动异步任务
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 启动线程执行下载任务 new Thread(downloadRun).start(); } /** * 下载线程 */ Runnable downloadRun = new Runnable(){ @Override public void run() { // TODO Auto-generated method stub updateListView(); } };出现错误二:11-05 19:03:36.299: E/AndroidRuntime(20215): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()在报错的方法前加Looper.prepare(); // 方法末尾加Looper.loop();
demo地址0分下载:http://download.csdn.net/detail/zqiang_55/4764266
-----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------
需要使用的是jsoup-1.8.1.jar包(到现在最新的) 如果需要看文档我下载请借一步到官网:http://jsoup.org/
package com.javen.Jsoup;import java.io.IOException;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;public class JsoupTest { static String url="http://www.cnblogs.com/zyw-205520/archive/2012/12/20/2826402.html"; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub BolgBody(); //test(); //Blog(); /* * Document doc = Jsoup.connect("http://www.oschina.net/") * .data("query", "Java") // 请求参数 .userAgent("I ’ m jsoup") // 设置 * User-Agent .cookie("auth", "token") // 设置 cookie .timeout(3000) // * 设置连接超时时间 .post(); */// 使用 POST 方法访问 URL /* * // 从文件中加载 HTML 文档 File input = new File("D:/test.html"); Document doc * = Jsoup.parse(input,"UTF-8","http://www.oschina.net/"); */ } /** * 获取指定HTML 文档指定的body * @throws IOException */ private static void BolgBody() throws IOException { // 直接从字符串中输入 HTML 文档 String html = "<html><head><title> 开源中国社区 </title></head>" + "<body><p> 这里是 jsoup 项目的相关文章 </p></body></html>"; Document doc = Jsoup.parse(html); System.out.println(doc.body()); // 从 URL 直接加载 HTML 文档 Document doc2 = Jsoup.connect(url).get(); String title = doc2.body().toString(); System.out.println(title); } /** * 获取博客上的文章标题和链接 */ public static void article() { Document doc; try { doc = Jsoup.connect("http://www.cnblogs.com/zyw-205520/").get(); Elements ListDiv = doc.getElementsByAttributeValue("class","postTitle"); for (Element element :ListDiv) { Elements links = element.getElementsByTag("a"); for (Element link : links) { String linkHref = link.attr("href"); String linkText = link.text().trim(); System.out.println(linkHref); System.out.println(linkText); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 获取指定博客文章的内容 */ public static void Blog() { Document doc; try { doc = Jsoup.connect("http://www.cnblogs.com/zyw-205520/archive/2012/12/20/2826402.html").get(); Elements ListDiv = doc.getElementsByAttributeValue("class","postBody"); for (Element element :ListDiv) { System.out.println(element.html()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
下面来介绍android中使用Jsoup异步解析网页的数据 请注意: 这里很容易遇到一个乱码的稳定
- 配置文件:AndroidManifest.xml中加 权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- layout的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <WebView android:id="@+id/webView" android:layout_width="fill_parent" android:layout_height="200dp" /> <ScrollView android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </ScrollView></LinearLayout>
3.主要异步加载数据的代码
package com.javen.aaa;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import android.app.Activity;import android.app.Dialog;import android.app.ProgressDialog;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.webkit.WebView;import android.widget.TextView;public class MainActivity extends Activity { private WebView webView; private TextView textView; private static final int DIALOG_KEY = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); webView = (WebView) findViewById(R.id.webView); textView=(TextView) findViewById(R.id.textView); try { ProgressAsyncTask asyncTask=new ProgressAsyncTask(webView,textView); asyncTask.execute(10000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String test() { StringBuffer buffer=new StringBuffer(); Document doc; try { doc = Jsoup.connect("http://www.cnblogs.com/zyw-205520/").get(); Elements ListDiv = doc.getElementsByAttributeValue("class","postTitle"); for (Element element :ListDiv) { Elements links = element.getElementsByTag("a"); for (Element link : links) { String linkHref = link.attr("href"); String linkText = link.text().trim(); buffer.append("linkHref=="+linkHref); buffer.append("linkText=="+linkText); System.out.println(linkHref); System.out.println(linkText); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return buffer.toString(); } // 弹出"查看"对话框 @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_KEY: { ProgressDialog dialog = new ProgressDialog(this); dialog.setMessage("获取数据中 请稍候..."); dialog.setIndeterminate(true); dialog.setCancelable(true); return dialog; } } return null; } public static String readHtml(String myurl) { StringBuffer sb = new StringBuffer(""); URL url; try { url = new URL(myurl); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), "gbk")); String s = ""; while ((s = br.readLine()) != null) { sb.append(s + "\r\n"); } } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } class ProgressAsyncTask extends AsyncTask<Integer, Integer, String> { private WebView webView; private TextView textView; public ProgressAsyncTask(WebView webView,TextView textView) { super(); this.webView=webView; this.textView=textView; } /** * 这里的Integer参数对应AsyncTask中的第一个参数 这里的String返回值对应AsyncTask的第三个参数 * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改 * 但是可以调用publish Progress方法触发onProgressUpdate对UI进行操作 */ @Override protected String doInBackground(Integer... params) { String str =null; Document doc = null; try {// String url ="http://www.cnblogs.com/zyw-205520/p/3355681.html";// // doc= Jsoup.parse(new URL(url).openStream(),"utf-8", url);// //doc = Jsoup.parse(readHtml(url));// //doc=Jsoup.connect(url).get();// str=doc.body().toString(); doc = Jsoup.connect("http://www.cnblogs.com/zyw-205520/archive/2012/12/20/2826402.html").get(); Elements ListDiv = doc.getElementsByAttributeValue("class","postBody"); for (Element element :ListDiv) { str=element.html(); System.out.println(element.html()); } Log.d("doInBackground", str.toString()); System.out.println(str); //你可以试试GBK或UTF-8 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return str.toString() ; //return test(); } /** * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值) * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置 */ @Override protected void onPostExecute(String result) { webView.loadData(result, "text/html;charset=utf-8", null); textView.setText(result); removeDialog(DIALOG_KEY); } // 该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置 @Override protected void onPreExecute() { showDialog(DIALOG_KEY); } /** * 这里的Intege参数对应AsyncTask中的第二个参数 * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行 * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作 */ @Override protected void onProgressUpdate(Integer... values) { } }}
- Android 使用Jsoup 抓取页面的数据
- android 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 异步抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 抓取页面的数据
- 使用Jsoup 简单抓取页面的数据
- 使用JSOUP抓取页面数据
- Route-map 初解
- POJ 1848 Tree
- CodeForces 489D Unbearable Controversy of Being
- 编程:带姓名的成绩单(2)
- ps 变换工具 + 油漆桶工具
- android 使用Jsoup 抓取页面的数据
- 从CSS到面向对象
- Java序列化与JSON序列化大比拼
- 每日一思
- feof多读一次问题分析
- Use CentOS 7 desktop on Dell Alienware 17
- OC学习篇之---类的初始化方法和点语法的使用
- NSTimer类的使用
- 6种常见的数据加载模式设计