Android抓取CSDN首页极客头条内容完整实例

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

分享给新手朋友。

要点:

1.使用ApacheHttpClient库实现GET请求。

2.异步请求处理。

3.正则表达式抓取自己需要的数据。

1.使用ApacheHttpClient库实现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" rel="external nofollow" target="_blank" onclick="LogClickCount(this,363);">宇宙员在太空中如何洗澡、睡觉、上厕所?</a></li> 

我们要抓取的内容是标题 和 URL地址。都用(.*?)代替

<li><a title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target="_blank" onclick="LogClickCount(this,363);">\1</a></li> 

对比上面,我们要抓取的内容都用(.*?)代替,这里“\1”是代表第一个(.*?)的内容。他们是重复内容。

同理如果我们用“\2”将代表与第二个括号相同内容。这里我们没有使用。

用工具测试通过,发现没问题,能找出。

再简化,我们删去一些对定位无关紧要的内容,这步简化要测试,保证匹配内容同上。

title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target="_blank" onclick="LogClickCount(this,363) 

我们发现target="_blank"onclick="LogClickCount(this,在其他地方也有,是不能区分的内容的匹配词,我们用.*?忽略。注意,不用括号,用括号是我们提取的内容。最后我们得到一个特征字串,通过下面特征字串可以在源码众多的字符中,

提取我们要的内容。

title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" .*?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();
	}
	/**
   * 新开辟线程处理联网操作
   */
	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 数据
   */
	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="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target="_blank" onclick="LogClickCountthis,363;">\1</a></li>
		//title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" .*?,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
   */
	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 网页内容的字符串
   */
	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);
	}
}

总结

以上就是本文关于Android抓取CSDN首页极客头条内容完整实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

(0)

相关推荐

  • Android编写简单的网络爬虫

    一.网络爬虫的基本知识 网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念.爬虫如何遍历网络呢,互联网可以看做是一张大图,每个页面看做其中的一个节点,页面的连接看做是有向边.图的遍历方式分为宽度遍历和深度遍历,但是深度遍历可能会在深度上过深的遍历或者陷入黑洞.所以,大多数爬虫不采用这种形式.另一方面,爬虫在按照宽度优先遍历的方式时候,会给待遍历的网页赋予一定优先级,这种叫做带偏好的遍历. 实际的爬虫是从一系列的种子链接开始.种子链接是起始节点,种子页面的超链接指向的页面是

  • Android利用爬虫实现模拟登录的实现实例

    Android利用爬虫实现模拟登录的实现实例 为了用手机登录校网时不用一遍一遍的输入账号密码,于是决定用爬虫抓取学校登录界面,然后模拟填写本次保存的账号.密码,模拟点击登录按钮.实现过程折腾好几个. 一开始选择的是htmlunit解析登录界面html,在pc上测的能实现,结果在android上运行不起来,因为htmlunit利用了javax中的类实现的解析,android不支持javax,所以就跑不起来. 不过pc还是ok的 实例代码: package com.yasin; import jav

  • Android抓取CSDN首页极客头条内容完整实例

    今天,写了个小代码.抓取首页中的极客头条.效果如图: 分享给新手朋友. 要点: 1.使用ApacheHttpClient库实现GET请求. 2.异步请求处理. 3.正则表达式抓取自己需要的数据. 1.使用ApacheHttpClient库实现GET请求. 使用Apache只需简单三步 HttpClient httpClient = new DefaultHttpClient(); //创建一个HttpClient HttpGet httpGet = new HttpGet("http://www

  • python抓取百度首页的方法

    本文实例讲述了python抓取百度首页的方法.分享给大家供大家参考.具体实现方法如下: import urllib def downURL(url,filename): try: fp=urllib.urlopen(url) except: print('download error') return 0 op=open(filename,'wb') while 1: s=fp.read() if not s: break op.write(s) fp.close() op.close() re

  • python requests抓取one推送文字和图片代码实例

    这篇文章主要介绍了python requests抓取one推送文字和图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 requests是Python中一个第三方库,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求.接下来将记录一下requests的使用: from bs4 import BeautifulSoup f

  • node.js抓取并分析网页内容有无特殊内容的js文件

    nodejs获取网页内容绑定data事件,获取到的数据会分几次相应,如果想全局内容匹配,需要等待请求结束,在end结束事件里把累积起来的全局数据进行操作! 举个例子,比如要在页面中找有没有www.baidu.com,不多说了,直接放代码: //引入模块 var http = require("http"), fs = require('fs'), url = require('url'); //写入文件,把结果写入不同的文件 var writeRes = function(p, r)

  • 用Python程序抓取网页的HTML信息的一个小实例

    抓取网页数据的思路有好多种,一般有:直接代码请求http.模拟浏览器请求数据(通常需要登录验证).控制浏览器实现数据抓取等.这篇不考虑复杂情况,放一个读取简单网页数据的小例子: 目标数据 将ittf网站上这个页面上所有这些选手的超链接保存下来. 数据请求 真的很喜欢符合人类思维的库,比如requests,如果是要直接拿网页文本,一句话搞定: doc = requests.get(url).text 解析html获得数据 以beautifulsoup为例,包含获取标签.链接,以及根据html层次结

  • Android编程实现QQ表情的发送和接收完整实例(附源码)

    本文实例讲述了Android编程实现QQ表情的发送和接收.分享给大家供大家参考,具体如下: 在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下QQ表情,图片资源完全copy的QQ.apk,解压就可以得到,这里不细说. 下面将该应用中的表情模块功能抽离出来,以便自己以后复习回顾.. 先看一下效果图: 首先进入界面:(完全仿照QQ) 点击一下上面的表情图标: 选择一些表情,输入一些文字混合: 点击发送: 可以看到文字和表情图片都一起显示出来了. 下面列出一些关键代码: 表情工具类Exp

  • Android Studio EditText点击图标清除文本内容的实例解析

    这篇文章是继自定义EditText样式之后的功能强化,对于实际应用项目有很大的参考意见,感兴趣的朋友可以移步上一篇,"Android Studion自定义EditText样式".具体清除EditText文本内容功能代码如下: package com.liheng; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; import

  • java抓取网页数据获取网页中所有的链接实例分享

    效果图 复制代码 代码如下: import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.regex.Matcher;import java.util.regex.Pattern; p

  • Android ViewPager无限循环滑动并可自动滚动完整实例

    对于ViewPager 广告页这个功能很多APP都有这个功能在网上也看过一些资料,我就在这把我自己完整的实现方法写出来吧 基础的ViewPager: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="ma

  • 如何使用python爬取csdn博客访问量

    最近学习了python和爬虫,想写一个程序练练手,所以我就想到了大家都比较关心的自己的博客访问量,使用python来获取自己博客的访问量,这也是后边我将要进行的项目的一部分,后边我会对博客的访问量进行分析,以折线图和饼图等可视化的方式展示自己博客被访问的情况,使自己能更加清楚自己的哪些博客更受关注,博客专家请勿喷,因为我不是专家,我听他们说专家本身就有这个功能. 一.网址分析 进入自己的博客页面,网址为:http://blog.csdn.net/xingjiarong 网址还是非常清晰的就是cs

随机推荐