這篇文章給大家分享的是有關(guān)Android如何抓取CSDN首頁(yè)極客頭條內(nèi)容的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
效果如圖:
分享給新手朋友。
要點(diǎn):
1.使用ApacheHttpClient庫(kù)實(shí)現(xiàn)GET請(qǐng)求。
2.異步請(qǐng)求處理。
3.正則表達(dá)式抓取自己需要的數(shù)據(jù)。
1.使用ApacheHttpClient庫(kù)實(shí)現(xiàn)GET請(qǐng)求。
使用Apache只需簡(jiǎn)單三步
HttpClient httpClient = new DefaultHttpClient(); //創(chuàng)建一個(gè)HttpClient HttpGet httpGet = new HttpGet(“http://www.csdn.net/”); //創(chuàng)建一個(gè)GET請(qǐng)求 HttpResponse response = httpClient.execute(httpGet); //發(fā)送GET請(qǐng)求,并響應(yīng)內(nèi)容
2.異步請(qǐng)求處理。
異步請(qǐng)求的實(shí)現(xiàn)也很簡(jiǎn)單,開(kāi)辟新線(xiàn)程執(zhí)行請(qǐng)求處理,請(qǐng)求完成通過(guò)Handler在主線(xiàn)程處理所獲得的數(shù)據(jù)。具體看代碼。
3.正則表達(dá)式抓取自己需要的數(shù)據(jù)。
這個(gè)更簡(jiǎn)單,我推薦一個(gè)工具RegexTester,使用方法在相關(guān)文檔。
我這里說(shuō)下,就算你什么正則表達(dá)式一點(diǎn)都不知道,你只要知道(.*?)就可以了。它可以讓你抓取基本上所有你需要的數(shù)據(jù)。
".*?"注意是三個(gè)字符一起,代表貪婪匹配任意數(shù)量的任意字符。可以簡(jiǎn)單的理解為任何字符。
如"a.*?b"對(duì)字符串"eabcd",進(jìn)行匹配,將找到"abcd",其中".*?"匹配"bc"。
我們需要抓取的內(nèi)容一般用"(.*?)"表示,注意這里是包含括號(hào)的。這很重要,用括號(hào)表示我們要提取的內(nèi)容。
我們具體分析CSDN首頁(yè)源代碼,下面每步操作都應(yīng)該在RegexTester測(cè)試進(jìn)行。
很容易找到,我們要抓取內(nèi)容的毎一條是如下格式。
<li><a title="宇宙員在太空中如何洗澡、睡覺(jué)、上廁所?" href="http://geek.csdn.net/news/detail/1478" rel="external nofollow" target="_blank" onclick="LogClickCount(this,363);">宇宙員在太空中如何洗澡、睡覺(jué)、上廁所?</a></li>
我們要抓取的內(nèi)容是標(biāo)題 和 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>
對(duì)比上面,我們要抓取的內(nèi)容都用(.*?)代替,這里“\1”是代表第一個(gè)(.*?)的內(nèi)容。他們是重復(fù)內(nèi)容。
同理如果我們用“\2”將代表與第二個(gè)括號(hào)相同內(nèi)容。這里我們沒(méi)有使用。
用工具測(cè)試通過(guò),發(fā)現(xiàn)沒(méi)問(wèn)題,能找出。
再簡(jiǎn)化,我們刪去一些對(duì)定位無(wú)關(guān)緊要的內(nèi)容,這步簡(jiǎn)化要測(cè)試,保證匹配內(nèi)容同上。
title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" target="_blank" onclick="LogClickCount(this,363)
我們發(fā)現(xiàn)target="_blank"onclick="LogClickCount(this,在其他地方也有,是不能區(qū)分的內(nèi)容的匹配詞,我們用.*?忽略。注意,不用括號(hào),用括號(hào)是我們提取的內(nèi)容。最后我們得到一個(gè)特征字串,通過(guò)下面特征字串可以在源碼眾多的字符中,
提取我們要的內(nèi)容。
title="(.*?)" href="(.*?)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" .*?363
注意如上內(nèi)容要在作為代碼字符串,要經(jīng)過(guò)一點(diǎn)處理,在每個(gè)"引號(hào)前加“\",
"title=\"(.*?)\" href=\"(.*?)\".*?363"
在代碼中是一段很短的代碼:
Pattern p = Pattern.compile("title=\"(.*?)\" href=\"(.*?)\".*?363"); Matcher m = p.matcher(csDNString); //csdn首頁(yè)的源代碼字符串 while (m.find()) { //循環(huán)查找匹配字串 MatchResult mr=m.toMatchResult(); Map<String, Object> map = new HashMap<String, Object>(); map.put("title", mr.group(1));//找到后group(1)是表達(dá)式第一個(gè)括號(hào)的內(nèi)容 map.put("url", mr.group(2));//group(2)是表達(dá)式第二個(gè)括號(hào)的內(nèi)容 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(); } /** * 新開(kāi)辟線(xiàn)程處理聯(lián)網(wǎng)操作 */ 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(); } /** * 聯(lián)網(wǎng)獲得數(shù)據(jù) * @return 數(shù)據(jù) */ 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; } /** * 處理聯(lián)網(wǎng)結(jié)果,顯示在listview * @return */ private Handler getHandler() { return new Handler(){ public void handleMessage(Message msg) { if (msg.what < 0) { Toast.makeText(MainActivity.this, "數(shù)據(jù)獲取失敗", Toast.LENGTH_sHORT).show(); } else { initListview(); } } } ; } /** * 在listview里顯示數(shù)據(jù) * @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請(qǐng)求URL,失敗時(shí)嘗試三次 * @param url 請(qǐng)求網(wǎng)址 * @return 網(wǎng)頁(yè)內(nèi)容的字符串 */ 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編碼轉(zhuǎn)化為字符串 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(); //設(shè)定連接超時(shí)和讀取超時(shí)時(shí)間 HttpConnectionParams.setConnectionTimeout(httpParams, 6000); HttpConnectionParams.setSoTimeout(httpParams, 30000); return new DefaultHttpClient(httpParams); } }
感謝各位的閱讀!關(guān)于“Android如何抓取CSDN首頁(yè)極客頭條內(nèi)容”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
分享題目:Android如何抓取CSDN首頁(yè)極客頭條內(nèi)容
網(wǎng)站URL:http://jinyejixie.com/article30/jjijpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、做網(wǎng)站、定制網(wǎng)站、App設(shè)計(jì)、網(wǎng)站營(yíng)銷(xiāo)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
移動(dòng)網(wǎng)站建設(shè)知識(shí)