Android抓取优快云首页极客头条内容--网页数据抓取

本文介绍了一个简单的Java程序,用于从优快云网站抓取极客头条的标题和链接。通过Apache HttpClient库发起GET请求并使用正则表达式解析所需数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

[html]  view plain  copy
  1. <li><a title="宇宙员在太空中如何洗澡、睡觉、上厕所?" href="http://geek.youkuaiyun.com/news/detail/1478" target="_blank" onclick="LogClickCount(this,363);">宇宙员在太空中如何洗澡、睡觉、上厕所?</a></li>  
我们要抓取的内容是标题 和 URL地址。都用(.*?)代替
[html]  view plain  copy
  1. <li><a title="(.*?)" href="(.*?)" target="_blank" onclick="LogClickCount(this,363);">\1</a></li>  
对比上面,我们要抓取的内容都用(.*?)代替,这里“\1 ”是代表第一个(.*?)的内容。他们是重复内容。
同理如果我们用“\2”将代表与第二个括号相同内容。这里我们没有使用。
用工具测试通过,发现没问题,能找出。
再简化,我们删去一些对定位无关紧要的内容,这步简化要测试,保证匹配内容同上。
[html]  view plain  copy
  1. title="(.*?)" href="(.*?)" target="_blank" onclick="LogClickCount(this,363)  
我们发现target="_blank" onclick="LogClickCount(this,在其他地方也有,是不能区分的内容的匹配词,我们用.*?忽略。注意,不用括号,用括号是我们提取的内容。最后我们得到一个特征字串,通过下面特征字串可以在源码众多的字符中,
提取我们要的内容。
[html]  view plain  copy
  1. title="(.*?)" href="(.*?)".*?363  
注意如上内容要在作为代码字符串,要经过一点处理,在每个"引号前加“\",
[java]  view plain  copy
  1. "title=\"(.*?)\" href=\"(.*?)\".*?363"  
在代码中是一段很短的代码:
[java]  view plain  copy
  1. Pattern p = Pattern.compile("title=\"(.*?)\" href=\"(.*?)\".*?363");  
  2. Matcher m = p.matcher(csdnString); //csdn首页的源代码字符串  
  3. while (m.find()) { //循环查找匹配字串  
  4.     MatchResult mr=m.toMatchResult();  
  5.     Map<String, Object> map = new HashMap<String, Object>();  
  6.     map.put("title", mr.group(1));//找到后group(1)是表达式第一个括号的内容  
  7.     map.put("url", mr.group(2));//group(2)是表达式第二个括号的内容  
  8.     result.add(map);  
  9. }  
具体代码如下:
[java]  view plain  copy
  1. public class MainActivity extends ListActivity {  
  2.     ListView listview;  
  3.     Handler handler;  
  4.     List<Map<String, Object>> data;  
  5.   
  6.     final String 优快云URL = "http://www.youkuaiyun.com/";  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         handler = getHandler();  
  12.         ThreadStart();  
  13.     }  
  14.     /** 
  15.      * 新开辟线程处理联网操作 
  16.      * @author Lai Huan 
  17.      * @created 2013-6-20 
  18.      */  
  19.     private void ThreadStart() {  
  20.         new Thread() {  
  21.             public void run() {  
  22.                 Message msg = new Message();  
  23.                 try {  
  24.                     data = getCsdnNetDate();  
  25.                     msg.what = data.size();  
  26.                 } catch (Exception e) {  
  27.                     e.printStackTrace();  
  28.                     msg.what = -1;  
  29.                 }  
  30.                 handler.sendMessage(msg);  
  31.             }  
  32.         }.start();  
  33.     }  
  34.     /** 
  35.      * 联网获得数据 
  36.      * @return 数据 
  37.      * @author Lai Huan 
  38.      * @created 2013-6-20 
  39.      */  
  40.     private List<Map<String, Object>> getCsdnNetDate() {  
  41.         List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();  
  42.         String csdnString = http_get(优快云URL);  
  43.         //<li><a title="(.*?)" href="(.*?)" target="_blank" onclick="LogClickCount this,363 ;">\1</a></li>  
  44.         //title="(.*?)" href="(.*?)".*?,363\)  
  45.         Pattern p = Pattern.compile("title=\"(.*?)\" href=\"(.*?)\".*?363");  
  46.         Matcher m = p.matcher(csdnString);  
  47.         while (m.find()) {  
  48.             MatchResult mr=m.toMatchResult();  
  49.             Map<String, Object> map = new HashMap<String, Object>();  
  50.             map.put("title", mr.group(1));  
  51.             map.put("url", mr.group(2));  
  52.             result.add(map);  
  53.         }  
  54.         return result;  
  55.     }  
  56.     /** 
  57.      * 处理联网结果,显示在listview 
  58.      * @return 
  59.      * @author Lai Huan 
  60.      * @created 2013-6-20 
  61.      */  
  62.     private Handler getHandler() {  
  63.         return new Handler(){  
  64.             public void handleMessage(Message msg) {  
  65.                 if (msg.what < 0) {  
  66.                     Toast.makeText(MainActivity.this"数据获取失败", Toast.LENGTH_SHORT).show();  
  67.                 }else {  
  68.                     initListview();  
  69.                 }  
  70.             }  
  71.         };  
  72.     }  
  73.     /** 
  74.      * 在listview里显示数据 
  75.      * @author Lai Huan 
  76.      * @created 2013-6-20 
  77.      */  
  78.     private void initListview() {  
  79.         listview = getListView();  
  80.         SimpleAdapter adapter = new SimpleAdapter(this, data,  
  81.                 android.R.layout.simple_list_item_1, new String[] { "title"},  
  82.                 new int[] { android.R.id.text1 });  
  83.         listview.setAdapter(adapter);  
  84.         listview.setOnItemClickListener(new OnItemClickListener() {  
  85.             @Override  
  86.             public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
  87.                     long arg3) {  
  88.                 Map<String, Object> map = data.get(arg2);  
  89.                 String url = (String)(map.get("url"));  
  90.                 Intent intent = new Intent(Intent.ACTION_VIEW);  
  91.                 intent .setData(Uri.parse(url));  
  92.                 startActivity(intent);  
  93.             }  
  94.         });  
  95.     }  
  96.   
  97.     /** 
  98.      * get请求URL,失败时尝试三次 
  99.      * @param url 请求网址 
  100.      * @return 网页内容的字符串 
  101.      * @author Lai Huan 
  102.      * @created 2013-6-20 
  103.      */  
  104.     private String http_get(String url) {  
  105.         final int RETRY_TIME = 3;  
  106.         HttpClient httpClient = null;  
  107.         HttpGet httpGet = null;  
  108.   
  109.         String responseBody = "";  
  110.         int time = 0;  
  111.         do {  
  112.             try {  
  113.                 httpClient = getHttpClient();  
  114.                 httpGet = new HttpGet(url);  
  115.                 HttpResponse response = httpClient.execute(httpGet);  
  116.                 if (response.getStatusLine().getStatusCode() == 200) {  
  117.                     //用utf-8编码转化为字符串  
  118.                     byte[] bResult = EntityUtils.toByteArray(response.getEntity());  
  119.                     if (bResult != null) {  
  120.                         responseBody = new String(bResult,"utf-8");  
  121.                     }  
  122.                 }  
  123.                 break;  
  124.             } catch (IOException e) {  
  125.                 time++;  
  126.                 if (time < RETRY_TIME) {  
  127.                     try {  
  128.                         Thread.sleep(1000);  
  129.                     } catch (InterruptedException e1) {  
  130.                     }  
  131.                     continue;  
  132.                 }  
  133.                 e.printStackTrace();  
  134.             } finally {  
  135.                 httpClient = null;  
  136.             }  
  137.         } while (time < RETRY_TIME);  
  138.   
  139.         return responseBody;  
  140.     }  
  141.   
  142.     private  HttpClient getHttpClient() {  
  143.         HttpParams httpParams = new BasicHttpParams();  
  144.         //设定连接超时和读取超时时间  
  145.         HttpConnectionParams.setConnectionTimeout(httpParams, 6000);  
  146.         HttpConnectionParams.setSoTimeout(httpParams, 30000);  
  147.         return new DefaultHttpClient(httpParams);  
  148.     }  
  149. }  
相关文档:
正则表达式30分钟入门教程 http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值