周末群里有人希望帮他搞个程序采集某个网站数据,虽然说没什么技术难点又不缺那点钱,但是好奇心还是比较重,没事看了看,最基本的基于SESSION的认证,POST个用户名密码即可,用java写的话我通常采用HttpClient,很强大,很通用,但是最近时不时有看过Jersey2的一些东西,貌似和我之前熟知的1.x差异挺大,就刚好拿来试试(不是接单帮搞数据,单纯的玩技术,采集别人数据的事我可不做)。
实践下来,发现Jersey2的API写起来更清爽了,因为是用来采集,这里只用了Jersey-client相关功能,期间遇到一些小问题,就是登陆成功后目标网站是301重定向到新页面的,而Jersey2的API调用后还保留在原始页面,最终导致SESSION无效,不能进行下一步操作,Stackoverflow上搜了下,最终解决了,很简单,如下
WebTarget target = client.target("http://reg.xxx.com/loginchk.do").property(ClientProperties.FOLLOW_REDIRECTS, false);
在WebTarget中注册property——ClientProperties.FOLLOW_REDIRECTS为false即可,不过很好奇的是,字面意思看,似乎设置为true更容易理解,不知是Jersey官方开发人员的想法和我们不大一样还是怎么滴,不过也不是我们关注的重点,就不在意这些细节了。
下面顺带贴出抓取的一些代码段。
package com.poorren.spider; import org.glassfish.jersey.client.ClientProperties; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.*; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * core * Created by William.Wei on 2016/3/13. */ public class Spider { private static Client client = ClientBuilder.newClient(); private static String cookie = null; private static Pattern patternItem = Pattern.compile("<dl>(.*)</dl>"); private static Pattern patternKey = Pattern.compile("<dt>(.*)</dt>"); private static Pattern patternValue = Pattern.compile("<dd>(.*)</dd>"); private static List<Map<String, String>> dataList = new ArrayList<>(); private static int index = 1; private static void login() { WebTarget target = client.target("http://reg.xxx.com/loginchk.do").property(ClientProperties.FOLLOW_REDIRECTS, false); Response response = target.request().post(Entity.form(new Form().param("username", "poorren").param("userPassword", "123654789"))); cookie = response.getHeaderString("Set-Cookie"); } public static Map<String, String> get(int id) { if (cookie == null) { login(); } WebTarget target = client.target("http://friend.xxx.com/usercontact.html").queryParam("userid", id); Response response = target.request().header("Cookie", cookie).get(); String html = response.readEntity(String.class); Matcher matcher = patternItem.matcher(html); Map<String, String> map = new HashMap<>(); while (matcher.find()) { String item = matcher.group(1); Matcher key = patternKey.matcher(item); Matcher value = patternValue.matcher(item); if (key.find() && value.find()) { map.put(key.group(1).trim(), value.group(1).trim()); } } return map; } }
是不是很简洁呢?
上一篇: Virtualbox 安装时发生严重错误[解决] 下一篇: JavaScript函数究竟是值传递还是引用传递?