今天,写了个小代码。抓取首页中的极客头条。效果如图:
分享给新手朋友。
要点:
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);"></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;"></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.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首页极客头条内容完整实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
总结以上是内存溢出为你收集整理的Android抓取CSDN首页极客头条内容完整实例全部内容,希望文章能够帮你解决Android抓取CSDN首页极客头条内容完整实例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)