package us.codecraft.webmagic; import us.codecraft.webmagic.utils.UrlUtils; import java.util.*; /** * Site定义一个待抓取的站点的各种信息。<br> * 这个类的所有getter方法,一般都只会被爬虫框架内部进行调用。<br> * * @author code4crafter@gmail.com <br> * Date: 13-4-21 * Time: 下午12:13 */ public class Site { private String domain; private String userAgent; private Map<String, String> cookies = new LinkedHashMap<String, String>(); private String charset; private List<String> startUrls = new ArrayList<String>(); private int sleepTime = 3000; private int retryTimes = 0; private static final Set<Integer> DEFAULT_STATUS_CODE_SET = new HashSet<Integer>(); private Set<Integer> acceptStatCode = DEFAULT_STATUS_CODE_SET; static { DEFAULT_STATUS_CODE_SET.add(200); } /** * 创建一个Site对象,等价于new Site() * * @return 新建的对象 */ public static Site me() { return new Site(); } /** * 为这个站点添加一个cookie,可用于抓取某些需要登录访问的站点。这个cookie的域名与{@link #getDomain()}是一致的 * * @param name cookie的名称 * @param value cookie的值 * @return this */ public Site addCookie(String name, String value) { cookies.put(name, value); return this; } /** * 为这个站点设置user-agent,很多网站都对user-agent进行了限制,不设置此选项可能会得到期望之外的结果。 * * @param userAgent userAgent * @return this */ public Site setUserAgent(String userAgent) { this.userAgent = userAgent; return this; } /** * 获取已经设置的所有cookie * * @return 已经设置的所有cookie */ public Map<String, String> getCookies() { return cookies; } /** * 获取已设置的user-agent * * @return 已设置的user-agent */ public String getUserAgent() { return userAgent; } /** * 获取已设置的domain * * @return 已设置的domain */ public String getDomain() { if (domain == null) { if (startUrls.size() > 0) { domain = UrlUtils.getDomain(startUrls.get(0)); } } return domain; } /** * 设置这个站点所在域名,必须项。<br> * 目前不支持多个域名的抓取。抓取多个域名请新建一个Spider。 * * @param domain 爬虫会抓取的域名 * @return this */ public Site setDomain(String domain) { this.domain = domain; return this; } /** * 设置页面编码,若不设置则自动根据Html meta信息获取。<br> * 一般无需设置encoding,如果发现下载的结果是乱码,则可以设置此项。<br> * * @param charset 编码格式,主要是"utf-8"、"gbk"两种 * @return this */ public Site setCharset(String charset) { this.charset = charset; return this; } /** * 获取已设置的编码 * * @return 已设置的domain */ public String getCharset() { return charset; } /** * 设置可接受的http状态码,仅当状态码在这个集合中时,才会读取页面内容。<br> * 默认为200,正常情况下,无须设置此项。<br> * 某些站点会错误的返回状态码,此时可以对这个选项进行设置。<br> * * @param acceptStatCode 可接受的状态码 * @return this */ public Site setAcceptStatCode(Set<Integer> acceptStatCode) { this.acceptStatCode = acceptStatCode; return this; } /** * 获取可接受的状态码 * * @return 可接受的状态码 */ public Set<Integer> getAcceptStatCode() { return acceptStatCode; } /** * 获取初始页面的地址列表 * * @return 初始页面的地址列表 */ public List<String> getStartUrls() { return startUrls; } /** * 增加初始页面的地址,可反复调用此方法增加多个初始地址。 * * @param startUrl 初始页面的地址 * @return this */ public Site addStartUrl(String startUrl) { this.startUrls.add(startUrl); return this; } /** * 设置两次抓取之间的间隔,避免对目标站点压力过大(或者避免被防火墙屏蔽...)。 * * @param sleepTime 单位毫秒 * @return this */ public Site setSleepTime(int sleepTime) { this.sleepTime = sleepTime; return this; } /** * 获取两次抓取之间的间隔 * * @return 两次抓取之间的间隔,单位毫秒 */ public int getSleepTime() { return sleepTime; } /** * 获取重新下载的次数,默认为0 * * @return 重新下载的次数 */ public int getRetryTimes() { return retryTimes; } /** * 设置获取重新下载的次数,默认为0 * * @return this */ public Site setRetryTimes(int retryTimes) { this.retryTimes = retryTimes; return this; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Site site = (Site) o; if (acceptStatCode != null ? !acceptStatCode.equals(site.acceptStatCode) : site.acceptStatCode != null) return false; if (!domain.equals(site.domain)) return false; if (!startUrls.equals(site.startUrls)) return false; if (charset != null ? !charset.equals(site.charset) : site.charset != null) return false; if (userAgent != null ? !userAgent.equals(site.userAgent) : site.userAgent != null) return false; return true; } public Task toTask() { return new Task() { @Override public String getUUID() { return Site.this.getDomain(); } @Override public Site getSite() { return Site.this; } @Override public void cron(String expr) { } }; } @Override public int hashCode() { int result = domain.hashCode(); result = 31 * result + (startUrls != null ? startUrls.hashCode() : 0); result = 31 * result + (userAgent != null ? userAgent.hashCode() : 0); result = 31 * result + (charset != null ? charset.hashCode() : 0); result = 31 * result + (acceptStatCode != null ? acceptStatCode.hashCode() : 0); return result; } }