android抓取贴吧内容,Android抓取CSDN首页极客头条内容完整实例

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

a2918c727c557bef52bd96bc9ad590c0.png

分享给新手朋友。

要点:

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" οnclick="LogClickCount(this,363)

我们发现target="_blank"οnclick="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首页极客头条内容完整实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值