httpclient可以用get和post方法访问网页并返回相应内容,然后在jsoup上对返回的内容作处理再显示在客户端上可以达到预期的效果。
post方法:
//post方法
public int post_http(String url,List<NameValuePair> params,HttpClient client) throws ClientProtocolException, IOException{
HttpPost post=new HttpPost(url);
HttpResponse response;
post.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);
post.setEntity(new UrlEncodedFormEntity(params, "gb2312"));
response=client.execute(post);
post.abort();
if(response.getFirstHeader("Location")==null){
return 0;
}else{
return 1;
}
}
post提交的数据:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("__VIEWSTATE", zhuangtai));
params.add(new BasicNameValuePair("tbYHM", id));
params.add(new BasicNameValuePair("tbPSW", pwd));
params.add(new BasicNameValuePair("ddlSF", "学生"));
params.add(new BasicNameValuePair("imgDL.x", "27"));
params.add(new BasicNameValuePair("imgDL.y", "11"));
httpclient会自动处理cookie等相关认证问题,只要使用同一个client就可以保持通讯。如:
HttpClient client_jiaowu=new DefaultHttpClient();
get方法:
//get方法
public String get_http(String url,HttpClient client){
String wangyeneirong = null; //保存网页内容
HttpResponse httpResponse; //建立响应
HttpGet get = new HttpGet(url); //建立get
try {
httpResponse = client.execute(get); //执行
HttpEntity entity = httpResponse.getEntity();
wangyeneirong=EntityUtils.toString(entity);
get.abort(); //关闭连接
return wangyeneirong;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
使用httpclient常见的问题:
一、例如登录一个网站的时候,提交了所有的数据依然还是无法正确登陆。
把所有的input标签里的内容都提交是一个办法,因为站点有设置__VIEWSTATE,或类似的状态码,总之有些页面是需要先取得状态码然后再提交才能正确登录的。
二、设置相应的头信息。
用httpwatch抓取正常访问时提交的数据,除了正确的提交各个参数外,有些站点会验证是否是浏览器访问,这时需要设置和httpwatch抓取的信息相应的头信息,如:
HttpGet get = new HttpGet(tushuguan); //建立get
get.setHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
get.setHeader("Host","210.38.32.201");
get.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
get.setHeader("Accept-Encoding","gzip,deflate,sdch");
get.setHeader("Accept-Language","zh-CN,zh;q=0.8");
get.setHeader("Cache-Control","max-age=0");
get.setHeader("Connection","keep-alive");
使用jsoup的常见问题:
jsoup不难使用,通过Jsoup.parse方法把文本载入doc,或Jsoup.connect方法直接访问链接获得页面内容并载入doc(对于一些复杂的页面不一定成功)。然后再对doc的内容进行筛选即可(当然这只是初级用法)。
select选择器:
方法:Element.select(String selector)和Elements.select(String selector)。
选择器概要(Selector overview)
- Tagname:通过标签查找元素(例如:a)
- ns|tag:通过标签在命名空间查找元素,例如:fb|name查找<fb:name>元素
- #id:通过ID查找元素,例如#logo
- .class:通过类型名称查找元素,例如.masthead
- [attribute]:带有属性的元素,例如[href]
- [^attr]:带有名称前缀的元素,例如[^data-]查找HTML5带有数据集(dataset)属性的元素
- [attr=value]:带有属性值的元素,例如[width=500]
- [attr^=value],[attr$=value],[attr*=value]:包含属性且其值以value开头、结尾或包含value的元素,例如[href*=/path/]
- [attr~=regex]:属性值满足正则表达式的元素,例如img[src~=(?i)\.(png|jpe?g)]
- *:所有元素,例如*
选择器组合方法
- el#id::带有ID的元素ID,例如div#logo
- el.class:带类型的元素,例如. div.masthead
- el[attr]:包含属性的元素,例如a[href]
- 任意组合:例如a[href].highlight
- ancestor child:继承自某祖(父)元素的子元素,例如.body p查找“body”块下的p元素
- parent > child:直接为父元素后代的子元素,例如: div.content > pf查找p元素,body > * 查找body元素的直系子元素
- siblingA + siblingB:查找由同级元素A前导的同级元素,例如div.head + div
- siblingA ~ siblingX:查找同级元素A前导的同级元素X例如h1 ~ p
- el, el, el:多个选择器组合,查找匹配任一选择器的唯一元素,例如div.masthead, div.logo
伪选择器(Pseudo selectors)
- :lt(n):查找索引值(即DOM树中相对于其父元素的位置)小于n的同级元素,例如td:lt(3)
- :gt(n):查找查找索引值大于n的同级元素,例如div p:gt(2)
- :eq(n) :查找索引值等于n的同级元素,例如form input:eq(1)
- :has(seletor):查找匹配选择器包含元素的元素,例如div:has(p)
- :not(selector):查找不匹配选择器的元素,例如div:not(.logo)
- :contains(text):查找包含给定文本的元素,大小写铭感,例如p:contains(jsoup)
- :containsOwn(text):查找直接包含给定文本的元素
- :matches(regex):查找其文本匹配指定的正则表达式的元素,例如div:matches((?i)login)
- :matchesOwn(regex):查找其自身文本匹配指定的正则表达式的元素
- 注意:上述伪选择器是0-基数的,亦即第一个元素索引值为0,第二个元素index为1等