Android如何抓取CSDN首页极客头条内容

这篇文章给大家分享的是有关Android如何抓取CSDN首页极客头条内容的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

效果如图:

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测试进行。

很容易找到,我们要抓取内容的毎一条是如下格式。

  • 宇宙员在太空中如何洗澡、睡觉、上厕所?
  • 我们要抓取的内容是标题 和 URL地址。都用(.*?)代替

  • \1
  • 对比上面,我们要抓取的内容都用(.*?)代替,这里“\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 map = new HashMap(); 
      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> 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> getCsdnNetDate() {
    		List> result = new ArrayList>();
    		String csdnString = http_get(CSDNURL);
    		//
  • \1
  •   //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 map = new HashMap(); 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 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首页极客头条内容
    本文网址:http://azwzsj.com/article/jjijpo.html