最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android抓取CSDN首頁(yè)極客頭條內(nèi)容完整實(shí)例

 更新時(shí)間:2018年01月06日 14:07:52   作者:laihuan99  
這篇文章主要介紹了Android抓取CSDN首頁(yè)極客頭條內(nèi)容完整實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下

今天,寫(xiě)了個(gè)小代碼。抓取首頁(yè)中的極客頭條。效果如圖:

分享給新手朋友。

要點(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)辟新線程執(zhí)行請(qǐng)求處理,請(qǐng)求完成通過(guò)Handler在主線程處理所獲得的數(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é)、上廁所?"  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)辟線程處理聯(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);
	}
}

總結(jié)

以上就是本文關(guān)于Android抓取CSDN首頁(yè)極客頭條內(nèi)容完整實(shí)例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • Android中Parcel用法詳解

    Android中Parcel用法詳解

    這篇文章主要介紹了Android中Parcel用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Parcel數(shù)據(jù)容器的原理與使用方法,需要的朋友可以參考下
    2016-06-06
  • 詳解Android如何設(shè)計(jì)一個(gè)全局可調(diào)用的ViewModel對(duì)象

    詳解Android如何設(shè)計(jì)一個(gè)全局可調(diào)用的ViewModel對(duì)象

    很多時(shí)候我們需要維護(hù)一個(gè)全局可用的ViewModel,因?yàn)檫@樣可以維護(hù)全局同一份數(shù)據(jù)源,且方便使用協(xié)程綁定App的生命周期,那如何設(shè)計(jì)全局可用的ViewModel對(duì)象,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Android判斷軟鍵盤彈出并隱藏的簡(jiǎn)單完美解決方法(推薦)

    Android判斷軟鍵盤彈出并隱藏的簡(jiǎn)單完美解決方法(推薦)

    下面小編就為大家?guī)?lái)一篇Android判斷軟鍵盤彈出并隱藏的簡(jiǎn)單完美解決方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • Android實(shí)現(xiàn)用戶登錄記住密碼功能

    Android實(shí)現(xiàn)用戶登錄記住密碼功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)用戶登錄記住密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解

    Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解

    這篇文章主要介紹了Android中使用socket通信實(shí)現(xiàn)消息推送的方法,文中舉了一個(gè)消息發(fā)送端和一個(gè)消息接收端以及服務(wù)器端的例子來(lái)說(shuō)明原理并且展示了客戶端的實(shí)現(xiàn),需要的朋友可以參考下
    2016-04-04
  • kotlin $ 字符串模版的使用詳解

    kotlin $ 字符串模版的使用詳解

    $ 在kotlin 中當(dāng)做字符串模版使用,作用就是在字符串里面識(shí)別自己定義的字符,這篇文章主要介紹了kotlin $ 字符串模版的使用,需要的朋友可以參考下
    2024-01-01
  • Android自定義ImageView實(shí)現(xiàn)在圖片上添加圖層效果

    Android自定義ImageView實(shí)現(xiàn)在圖片上添加圖層效果

    這篇文章給大家主要介紹了利用Android自定義ImageView如何實(shí)現(xiàn)在圖片上添加圖層的效果,實(shí)現(xiàn)的效果類似在圖片增加秒殺、搶光等標(biāo)簽圖片,對(duì)大家開(kāi)發(fā)的時(shí)候具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • android實(shí)現(xiàn)倒計(jì)時(shí)功能的方法

    android實(shí)現(xiàn)倒計(jì)時(shí)功能的方法

    這篇文章主要為大家詳細(xì)介紹了兩種android實(shí)現(xiàn)倒計(jì)時(shí)功能的方法,具有一定的實(shí)用性,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Android?Admob接入原理及完整教程示例

    Android?Admob接入原理及完整教程示例

    這篇文章主要為大家介紹了Android?Admob接入原理及完整教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Android通知欄增加快捷開(kāi)關(guān)的功能實(shí)現(xiàn)教程

    Android通知欄增加快捷開(kāi)關(guān)的功能實(shí)現(xiàn)教程

    對(duì)于Android來(lái)說(shuō)其中一項(xiàng)很方便的操作便是下拉菜單,下拉菜單欄可以快捷打開(kāi)某項(xiàng)設(shè)置,這篇文章主要給大家介紹了關(guān)于Android通知欄增加快捷開(kāi)關(guān)的功能實(shí)現(xiàn),需要的朋友可以參考下
    2023-01-01

最新評(píng)論

遂川县| 四会市| 延吉市| 垫江县| 天全县| 安平县| 金秀| 恩平市| 平乐县| 湘西| 萨嘎县| 修文县| 潜江市| 镇巴县| 万年县| 芜湖县| 海淀区| 农安县| 宁河县| 那坡县| 永修县| 九龙城区| 朝阳区| 文山县| 天祝| 静乐县| 闽侯县| 满城县| 翁牛特旗| 黄梅县| 凤城市| 汕尾市| 麻城市| 昌乐县| 云南省| 烟台市| 永泰县| 宣化县| 吉首市| 扎囊县| 南漳县|