예제 #1
0
// 生成真实的url
// 传来的url可能是http://a.com, 也可能是a.com
// getRelativeUrl传来的可以是http://a.com
// url = a.com/a/?id=12&id=1221, 那么genUrl=a.com/a/index.html?id=121
func (this *Crawler) genUrl(url string) string {
	// 去掉?后面的
	queryParam, fragment := "", "" // 包含?,#
	pos := strings.Index(url, "?")
	if pos != -1 {
		queryParam = util.Substring(url, pos)
		url = util.Substr(url, 0, pos)
	} else {
		pos = strings.Index(url, "#")
		if pos != -1 {
			fragment = util.Substring(url, pos)
			url = util.Substr(url, 0, pos)
		}
	}

	// 如果url == host
	if url == this.host || url == this.schemeAndHost {
		return url + "/" + this.defaultFilename + queryParam + fragment
	}

	genFilename, needApend := this.genFilename(url)
	if genFilename != "" {
		if needApend {
			url += "/" + genFilename + queryParam + fragment
		} else {
			// 是a.php => a.html
			urlArr := strings.Split(url, "/")
			urlArr = urlArr[:len(urlArr)-1]
			url = strings.Join(urlArr, "/") + "/" + genFilename
		}
	}

	return url
}
예제 #2
0
// 入口
func (this *Crawler) Fetch(url, targetPath string) {
	url = strings.TrimSpace(url)

	this.parseUrl(url)

	// 保存路径
	this.doTargetPath(targetPath)

	// 去掉scheme
	// a.com, a.com/index.html
	url = util.Substring(url, len(this.scheme))

	//	url2, ok := this.getRalativeUrl("a.com/b/c/d/kk/eee.html", "http://a.com/e/c/d/kk")
	//	println(url2)
	//	println(ok)
	//	return

	this.goDo(url, false)
	this.w.Wait()

	// 处理异常
	this.doExceptionUrl()
}
예제 #3
0
// url : a.com/a/b/d.html
// a.com/a/b/c genFilename: c_leaui_index.html
// 生成子的相对目录有用
func (this *Crawler) doHTML(pUrl, realPUrl, content string) (children []string) {
	regular := "(?i)(src=|href=)[\"']([^#].*?)[\"']"
	reg := regexp.MustCompile(regular)
	re := reg.FindAllStringSubmatch(content, -1)

	log.Println(pUrl + " => " + realPUrl)
	log.Println(pUrl + " 含有: ")
	//log.Println(re);

	baseDir := filepath.Dir(realPUrl)
	for _, each := range re {
		// 为了完整替换
		// 只替换src=""里的会有子串的问题, 一个url是另一个url子串
		rawFullUrl := each[0]       // src='http://www.uiueux.com/wp/webzine/wp-content/themes/webzine/js/googlefont.js.php?ver=1.6.4'
		rawFullUrlPrefix := each[1] // src=

		// http://a.com/, /a/b/c/d.html, /a/b.jgp
		// 如果是/a/b.jpg, 那么是相对host的, 而不是本文件的路径
		rawCUrl := each[2]
		cUrl := rawCUrl // strings.TrimRight(rawCUrl, "/") // 万一就是/呢?

		// 如果一个链接以//开头, 那么省略了http:, 如果以/开头, 则相对于host
		prefixNotHttp := false
		if strings.HasPrefix(cUrl, "//") {
			cUrl = this.scheme + util.Substring(cUrl, 2)
			prefixNotHttp = true
		} else if strings.HasPrefix(cUrl, "/") {
			cUrl = this.schemeAndHost + cUrl
		}

		// 如果这个url是一个目录, 新建一个文件
		// 如果这个url是以http://a.com开头的, host是一样的,
		// 那么content的url是相对于该url
		// 生成的url, 如果是目录, 会生成一个文件
		cRealUrl, ok := this.getRalativeUrl(realPUrl, cUrl)

		// 错误, 不是本页面, 本host的页面
		if ok == -1 {
			// 如果之前//替换成了http://
			if prefixNotHttp {
				content = strings.Replace(content, rawFullUrl, rawFullUrlPrefix+"\""+cRealUrl+"\"", -1)
			}
			continue
		}
		// 表示已处理过, 是相对目录了, 必须把内容的替换掉
		// 但要处理的还是之前的链接http://
		if ok == 1 {
			cRealUrl = strings.Trim(cRealUrl, "/")
			// 把//变成/
			for strings.Index(cRealUrl, "//") != -1 {
				cRealUrl = strings.Replace(cRealUrl, "//", "/", -1)
			}
			log.Println(rawCUrl + " >>>>>> " + cRealUrl)
			content = strings.Replace(content, rawFullUrl, rawFullUrlPrefix+"\""+cRealUrl+"\"", -1)
			cUrl = strings.Replace(cUrl, this.scheme, "", 1) // 把sheme去掉, do
			children = append(children, cUrl)                // 不需要clean
		} else {
			children = append(children, this.cleanUrl(baseDir+"/"+cRealUrl))
		}
	}

	// 把content保存起来
	if !this.writeFile(realPUrl, content) {
		return
	}

	// this.t++
	// return

	return
}