周末群里有人希望帮他搞个程序采集某个网站数据,虽然说没什么技术难点又不缺那点钱,但是好奇心还是比较重,没事看了看,最基本的基于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;
    }
}

是不是很简洁呢?