Android抓取CSDN首页极客头条内容--网页数据抓取

今天,写了个小代码。抓取首页中的极客头条。效果如图:

分享给新手朋友。
要点:
1. 使用Apache HttpClient库实现GET请求。
2. 异步请求处理。
3. 正则表达式抓取自己需要的数据。
1. 使用Apache HttpClient库实现GET请求。
使用Apache只需简单三步

HttpClient httpClient = new DefaultHttpClient();  //创建一个HttpClient

HttpGet httpGet = new HttpGet(“http://www.csdn.net/”); //创建一个GET请求

HttpResponse response = httpClient.execute(httpGet); //发送GET请求,并响应内容
2. 异步请求处理。
异步请求的实现也很简单,开辟新线程执行请求处理,请求完成通过Handler在主线程处理所获得的数据。具体看代码。
3. 正则表达式抓取自己需要的数据。
这个更简单,我推荐一个工具RegexTester,使用方法在相关文档。
我这里说下,就算你什么正则表达式一点都不知道,你只要知道(.*?)就可以了。它可以让你抓取基本上所有你需要的数据。
".*?"注意是三个字符一起,代表贪婪匹配任意数量的任意字符。可以简单的理解为任何字符。
如"a.*?b"对字符串"eabcd",进行匹配,将找到"abcd",其中".*?"匹配"bc"。
我们需要抓取的内容一般用"(.*?)"表示,注意这里是包含括号的。这很重要,用括号表示我们要提取的内容。
我们具体分析CSDN首页源代码,下面每步操作都应该在RegexTester测试进行。
很容易找到,我们要抓取内容的毎一条是如下格式。

<li><a title="宇宙员在太空中如何洗澡、睡觉、上厕所?" href="http://geek.csdn.net/news/detail/1478" target="_blank" οnclick="LogClickCount(this,363);">宇宙员在太空中如何洗澡、睡觉、上厕所?</a></li>
我们要抓取的内容是标题 和 URL地址。都用(.*?)代替
<li><a title="(.*?)" href="(.*?)" target="_blank" οnclick="LogClickCount(this,363);">\1</a></li>
对比上面,我们要抓取的内容都用(.*?)代替,这里“\1 ”是代表第一个(.*?)的内容。他们是重复内容。
同理如果我们用“\2”将代表与第二个括号相同内容。这里我们没有使用。
用工具测试通过,发现没问题,能找出。
再简化,我们删去一些对定位无关紧要的内容,这步简化要测试,保证匹配内容同上。
title="(.*?)" href="(.*?)" target="_blank" οnclick="LogClickCount(this,363)
我们发现target="_blank" οnclick="LogClickCount(this,在其他地方也有,是不能区分的内容的匹配词,我们用.*?忽略。注意,不用括号,用括号是我们提取的内容。最后我们得到一个特征字串,通过下面特征字串可以在源码众多的字符中,
提取我们要的内容。
title="(.*?)" href="(.*?)".*?363
注意如上内容要在作为代码字符串,要经过一点处理,在每个"引号前加“\",
"title=\"(.*?)\" href=\"(.*?)\".*?363"
在代码中是一段很短的代码:
Pattern p = Pattern.compile("title=\"(.*?)\" href=\"(.*?)\".*?363");
Matcher m = p.matcher(csdnString); //csdn首页的源代码字符串
while (m.find()) { //循环查找匹配字串
    MatchResult mr=m.toMatchResult();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("title", mr.group(1));//找到后group(1)是表达式第一个括号的内容
    map.put("url", mr.group(2));//group(2)是表达式第二个括号的内容
    result.add(map);
}
具体代码如下:
public class MainActivity extends ListActivity {
	ListView listview;
	Handler handler;
	List<Map<String, Object>> data;

	final String CSDNURL = "http://www.csdn.net/";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = getHandler();
        ThreadStart();
    }
    /**
     * 新开辟线程处理联网操作
     * @author Lai Huan
     * @created 2013-6-20
     */
	private void ThreadStart() {
		new Thread() {
			public void run() {
				Message msg = new Message();
				try {
					data = getCsdnNetDate();
					msg.what = data.size();
				} catch (Exception e) {
					e.printStackTrace();
					msg.what = -1;
				}
				handler.sendMessage(msg);
			}
		}.start();
	}
	/**
	 * 联网获得数据
	 * @return 数据
	 * @author Lai Huan
	 * @created 2013-6-20
	 */
	private List<Map<String, Object>> getCsdnNetDate() {
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		String csdnString = http_get(CSDNURL);
		//<li><a title="(.*?)" href="(.*?)" target="_blank" οnclick="LogClickCount\(this,363\);">\1</a></li>
		//title="(.*?)" href="(.*?)".*?,363\)
		Pattern p = Pattern.compile("title=\"(.*?)\" href=\"(.*?)\".*?363");
		Matcher m = p.matcher(csdnString);
		while (m.find()) {
			MatchResult mr=m.toMatchResult();
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("title", mr.group(1));
			map.put("url", mr.group(2));
			result.add(map);
		}
		return result;
	}
	/**
	 * 处理联网结果,显示在listview
	 * @return
	 * @author Lai Huan
	 * @created 2013-6-20
	 */
	private Handler getHandler() {
    	return new Handler(){
			public void handleMessage(Message msg) {
				if (msg.what < 0) {
					Toast.makeText(MainActivity.this, "数据获取失败", Toast.LENGTH_SHORT).show();
				}else {
					initListview();
				}
			}
        };
	}
	/**
	 * 在listview里显示数据
	 * @author Lai Huan
	 * @created 2013-6-20
	 */
	private void initListview() {
		listview = getListView();
		SimpleAdapter adapter = new SimpleAdapter(this, data,
				android.R.layout.simple_list_item_1, new String[] { "title"},
				new int[] { android.R.id.text1 });
		listview.setAdapter(adapter);
		listview.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				Map<String, Object> map = data.get(arg2);
				String url = (String)(map.get("url"));
				Intent intent = new Intent(Intent.ACTION_VIEW);
				intent .setData(Uri.parse(url));
				startActivity(intent);
			}
		});
	}

	/**
	 * get请求URL,失败时尝试三次
	 * @param url 请求网址
	 * @return 网页内容的字符串
	 * @author Lai Huan
	 * @created 2013-6-20
	 */
	private String http_get(String url) {
		final int RETRY_TIME = 3;
		HttpClient httpClient = null;
		HttpGet httpGet = null;

		String responseBody = "";
		int time = 0;
		do {
			try {
				httpClient = getHttpClient();
				httpGet = new HttpGet(url);
				HttpResponse response = httpClient.execute(httpGet);
				if (response.getStatusLine().getStatusCode() == 200) {
					//用utf-8编码转化为字符串
					byte[] bResult = EntityUtils.toByteArray(response.getEntity());
					if (bResult != null) {
						responseBody = new String(bResult,"utf-8");
					}
				}
				break;
			} catch (IOException e) {
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				e.printStackTrace();
			} finally {
				httpClient = null;
			}
		} while (time < RETRY_TIME);

		return responseBody;
	}

	private  HttpClient getHttpClient() {
		HttpParams httpParams = new BasicHttpParams();
		//设定连接超时和读取超时时间
		HttpConnectionParams.setConnectionTimeout(httpParams, 6000);
		HttpConnectionParams.setSoTimeout(httpParams, 30000);
		return new DefaultHttpClient(httpParams);
	}
}
相关文档:
正则表达式30分钟入门教程 http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html

  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
[入门数据分析的第一堂课]这是一门为数据分析小白量身打造的课程,你从网络或者公众号收集到很多关于数据分析的知识,但是它们零散不成体系,所以第一堂课首要目标是为你介绍:Ø  什么是数据分析-知其然才知其所以然Ø  为什么要学数据分析-有目标才有动力Ø  数据分析的学习路线-有方向走得更快Ø  数据分析的模型-分析之道,快速形成分析思路Ø  应用案例及场景-分析之术,掌握分析方法[哪些同学适合学习这门课程]想要转行做数据分析师的,零基础亦可工作中需要数据分析技能的,例如运营、产品等对数据分析感兴趣,想要更多了解的[你的收获]n  会为你介绍数据分析的基本情况,为你展现数据分析的全貌。让你清楚知道自己该如何在数据分析地图上行走n  会为你介绍数据分析的分析方法和模型。这部分是讲数据分析的道,只有学会底层逻辑,能够在面对问题时有自己的想法,才能够下一步采取行动n  会为你介绍数据分析的数据处理和常用分析方法。这篇是讲数据分析的术,先有道,后而用术来实现你的想法,得出最终的结论。n  会为你介绍数据分析的应用。学到这里,你对数据分析已经有了初步的认识,并通过一些案例为你展现真实的应用。[专享增值服务]1:一对一答疑         关于课程问题可以通过微信直接询问老师,获得老师的一对一答疑2:转行问题解答         在转行的过程中的相关问题都可以询问老师,可获得一对一咨询机会3:打包资料分享         15本数据分析相关的电子书,一次获得终身学习

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值