/// <summary> /// 操作一段html文本或者css文本,将其中使用样式background:url(...)指定的图片下载到本地,并更改路径 /// </summary> /// <param name="content">一段html或者css文本</param> /// <param name="cssUrl">css文件的url,如果是内嵌css则此url为css所在页面的url</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载图片存放的目录</param> /// <param name="async">是否异步下载</param> /// <param name="dic">记录异步下载信息的字典</param> /// <returns>返回替换后的文本</returns> internal string ReplaceBackgroundUrl(string content, string cssUrl, DirConfig dirConfig, string referenceDir, string saveDir, bool async, Dictionary <string, string> dic) { //将css里面引用的图片下载到本地,并且然后替换css里的图片引用路径 content = RegexCollection.RegCssImgUrl.Replace(content, delegate(Match match) { return(this.MatchUrl(match, dirConfig, cssUrl, referenceDir, saveDir, "src", delegate(string url) { //获取css里面引用图片的绝对路径,同时干掉图片url开头和结尾的引号,以免造成悲剧图片不显示的问题(例如 style="background:url("xxx.jpg");" ,如果不干掉图片地址中的引号就会出问题) return Regex.Replace(url, @"^("|'|"")|("|""|')$", ""); }, null, async, dic)); }); return(content); }
/// <summary> /// 替换将js、css、图片、flash等文件下载到本地后,调用此方法获取在页面中引用本地文件的路径 /// </summary> /// <param name="match">匹配到的js、css、图片、flash等标签的正则实例</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="resourceUrl">当前html页面或者css文件的url。此url用于将其内容中的相对地址转换为绝对地址并下载</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载文件存放的目录</param> /// <param name="regGroupName">指定匹配url的正则分组的组名</param> /// <param name="urlHandle">指定对匹配url进行处理的函数回调</param> /// <param name="downloadHandle">指定自定义下载处理的函数回调,此回调返回下载文件的本地路径或者占位符</param> /// <returns>返回替换后的标签字符串</returns> internal string MatchUrl(Match match, DirConfig dirConfig, string resourceUrl, string referenceDir, string saveDir, string regGroupName, MatchCallback urlHandle, MatchCallback downloadHandle) { return(MatchUrl(match, dirConfig, resourceUrl, referenceDir, saveDir, regGroupName, urlHandle, downloadHandle, false, null)); }
/// <summary> /// 替换将js、css、图片、flash等文件下载到本地后,调用此方法获取在页面中引用本地文件的路径 /// </summary> /// <param name="match">匹配到的js、css、图片、flash等标签的正则实例</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="resourceUrl">当前html页面或者css文件的url。此url用于将其内容中的相对地址转换为绝对地址并下载</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载文件存放的目录</param> /// <param name="regGroupName">指定匹配url的正则分组的组名</param> /// <param name="urlHandle">指定对匹配url(也就是href或者src)进行处理的函数回调,此回调主要对url进行一些处理(例如去引号等等)</param> /// <param name="downloadHandle">指定自定义下载处理的函数回调,此回调返回下载文件的本地路径或者占位符</param> /// <param name="async">是否异步下载</param> /// <param name="dic">记录异步下载信息的字典</param> /// <returns>返回替换后的标签字符串</returns> internal string MatchUrl(Match match, DirConfig dirConfig, string resourceUrl, string referenceDir, string saveDir, string regGroupName, MatchCallback urlHandle, MatchCallback downloadHandle, bool async, Dictionary <string, string> dic) { //文件的地址(可能是相对也可能是绝对)、文件的绝对Url地址、以及保存到本地以后的本地路径 string href, url, localPath = ""; href = match.Groups[regGroupName].Value; if (null != urlHandle) { href = urlHandle(href); } url = PathUtility.ConvertToAbsoluteHref(resourceUrl ?? this.pageUrl, href); //如果设置了根据网站url结构按对应目录存储资源,则重新设置保存目录的路径 if (dirConfig.UseWebSite) { saveDir = PathUtility.GetSaveDir(this.PageUrl, url, dirConfig.HtmlDirPath); } //如果使用异步下载 if (async) { //如果未指定异步下载函数 if (null == downloadHandle) { localPath = this.GetPlaceHolder(); //开始异步下载资源 Spider.SaveResourceAsync(url, saveDir, new Action <string>(delegate(string filePath) { lock (dic) { dic[localPath] = null == filePath ? url : PathUtility.GetRelativePath(referenceDir, filePath); } })); } else { localPath = downloadHandle(url); } if (!dic.ContainsKey(localPath)) { lock (dic) { dic.Add(localPath, null); } } }//如果使用同步下载 else { if (null == downloadHandle) { //保存文件,如果成功,则返回文件保存后的本地路 localPath = Spider.SaveResource(url, saveDir); } else { localPath = downloadHandle(url); } //如果保存失败,则引用绝对url地址 if (string.IsNullOrEmpty(localPath)) { localPath = url; } else { localPath = PathUtility.GetRelativePath(referenceDir, localPath); } } //使用localPath替换html内容中的引用路径 return(match.Value.Replace(href, localPath)); }
/// <summary> ///使用同步方式下载,将html内容保存为html文件,并将html内容中引用的图片,css,js,flash都保存到本地,然后将html内容中引用的地址都转换为相对地址 /// </summary> /// <param name="fileName">保存的文件名</param> /// <param name="ignoreScript">保存的时候是否忽略Script标签,若为true,则忽略JS</param> /// <param name="dirConfig">页面下载文件夹相关配置信息</param> /// <returns>如果下载成功,返回文件的本地路径,否则返回null</returns> public string SaveHtmlAndResource(string fileName, bool ignoreScript, DirConfig dirConfig) { string htmlContent = this.html; if (!dirConfig.CheckLegal()) { throw new SpiderException("路径配置不在统一磁盘下"); } dirConfig.CreateDir(); if (string.IsNullOrEmpty(this.pageUrl)) { throw new SpiderException("未指定当前url"); } //如果忽略JS if (ignoreScript) { htmlContent = this.FilterScript(); } #region 保存所有css和css中引用的图片 htmlContent = RegexCollection.RegCssLink.Replace(htmlContent, delegate(Match match) { //由于css文件里有可能引用图片,所以在此处需要自定义css文件下载函数,将css文件中的图片下载到本地然后替换css文件中的引用路径 return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.CssDirPath, "src", null, delegate(string cssUrl) { //css内容、css保存路径 string cssContent, cssSavePath = cssUrl; CHttpWebRequest cRequest; CHttpWebResponse cResponse; //请求css文件 cRequest = Spider.CreateRequest(cssUrl); cRequest.SetHeader("Referer", this.PageUrl); cResponse = Spider.Get(cRequest); //如果请求成功 if (cResponse.Success) { using (cResponse) { //确定css文件保存的绝对路径 cssSavePath = dirConfig.UseWebSite ? Path.GetFullPath(PathUtility.GetSaveDir(this.PageUrl, cssUrl, dirConfig.HtmlDirPath) + cResponse.GetFileName()) : Path.GetFullPath(dirConfig.CssDirPath + "\\" + cResponse.GetFileName()); //获取css内容 cssContent = cResponse.GetContent(null, false); //下载css里引用的图片,并替换css内容中图片地址的引用 cssContent = this.ReplaceBackgroundUrl(cssContent, cssUrl, dirConfig, Path.GetDirectoryName(cssSavePath), dirConfig.ImgDirPath, false, null); //将css保存到本地 cssSavePath = FileUtility.SaveText(cssSavePath, cssContent, cResponse.GetEncoding()); } } //返回保存以后的css本地路径 return cssSavePath; })); }); #endregion #region 保存所有JS htmlContent = RegexCollection.RegScriptLink.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.JsDirPath, "src", null, null)); }); #endregion #region 保存所有图片 htmlContent = RegexCollection.RegImg.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, "src", null, null)); }); #endregion #region 保存所有Flash htmlContent = RegexCollection.RegFlash.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.FlashDirPath, "src", null, null)); }); #endregion #region 当前页面内嵌css中的图片 htmlContent = this.ReplaceBackgroundUrl(htmlContent, this.PageUrl, dirConfig, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, false, null); #endregion return(FileUtility.SaveText(Path.GetFullPath(dirConfig.HtmlDirPath + "\\" + fileName), htmlContent, this.encode)); }
/// <summary> ///使用异步方式下载,将html内容保存为html文件,并将html内容中引用的图片,css,js,flash都保存到本地,然后将html内容中引用的地址都转换为相对地址 /// </summary> /// <param name="fileName">保存的文件名</param> /// <param name="ignoreScript">保存的时候是否忽略Script标签,若为true,则忽略JS</param> /// <param name="dirConfig">页面下载文件夹相关配置信息</param> /// <returns>如果下载成功,返回文件的本地路径,否则返回null</returns> public string AsyncSaveHtmlAndResource(string fileName, bool ignoreScript, DirConfig dirConfig) { //当前的html内容 string htmlContent = this.html; //一个字典,key是资源地址的在html中的占位符,value是资源下载到本地的路径(如果未下载成功则是资源的url) Dictionary <string, string> dic = new Dictionary <string, string>(200); if (!dirConfig.CheckLegal()) { throw new SpiderException("路径配置不在统一磁盘下"); } dirConfig.CreateDir(); if (string.IsNullOrEmpty(this.pageUrl)) { throw new SpiderException("未指定当前url"); } //如果忽略JS if (ignoreScript) { htmlContent = this.FilterScript(); } #region 保存所有css和css中引用的图片 htmlContent = RegexCollection.RegCssLink.Replace(htmlContent, delegate(Match match) { //由于css文件里有可能引用图片,所以在此处需要自定义css文件下载函数,将css文件中的图片下载到本地然后替换css文件中的引用路径 return(this.MatchUrl(match, dirConfig, this.PageUrl, dirConfig.HtmlDirPath, dirConfig.CssDirPath, "src", null, delegate(string cssUrl) { //css引用在html中的占位符 string placeHolder = this.GetPlaceHolder(); //css文件在本地的目录 string filePath; //异步下载css文件中引用图片需要的字典 Dictionary <string, string> dicPlaceCss = new Dictionary <string, string>(20); CHttpWebRequest cRequest; //请求css文件 cRequest = Spider.CreateRequest(cssUrl); cRequest.SetHeader("Referer", this.pageUrl); #region 异步下载css文件 Spider.AsyncGet(cRequest, delegate(CHttpWebResponse cResponse) { //css文件内容 string cssContent; //css文件保存路径 string cssSavePath; //如果下载成功 if (cResponse.Success) { using (cResponse) { //确定css保存的绝对路径 cssSavePath = dirConfig.UseWebSite ? Path.GetFullPath(PathUtility.GetSaveDir(this.PageUrl, cssUrl, dirConfig.HtmlDirPath) + cResponse.GetFileName()) : Path.GetFullPath(dirConfig.CssDirPath + "\\" + cResponse.GetFileName()); //获取css内容 cssContent = cResponse.GetContent(null, false); //异步下载css里引用的图片,并替换css内容中图片地址的引用 cssContent = this.ReplaceBackgroundUrl(cssContent, cssUrl, dirConfig, Path.GetDirectoryName(cssSavePath), dirConfig.ImgDirPath, true, dicPlaceCss); //确定异步下载都已经下载完成,将css内容中的占位符替换为图片下载完成后对应的相对路径 cssContent = this.ReplacePlaceHolder(cssContent, dicPlaceCss); //保存css文件,获取保存以后的本地路径 filePath = FileUtility.SaveText(cssSavePath, cssContent, cResponse.GetEncoding()); //css中的图片都下载完成并且css文件也下载完成,此处设置占位符对应的引用路径 lock (dic) { //将css文件本地路径转换为一个引用路径 dic[placeHolder] = filePath == null ? cssUrl : PathUtility.GetRelativePath(dirConfig.HtmlDirPath, filePath); } } } }); #endregion //返回占位符 return placeHolder; }, true, dic)); }); #endregion #region 保存所有JS htmlContent = RegexCollection.RegScriptLink.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.JsDirPath, "src", null, null, true, dic)); }); #endregion #region 保存所有图片 htmlContent = RegexCollection.RegImg.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, "src", null, null, true, dic)); }); #endregion #region 保存所有Flash htmlContent = RegexCollection.RegFlash.Replace(htmlContent, delegate(Match match) { return(this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.FlashDirPath, "src", null, null, true, dic)); }); #endregion #region 当前页面内嵌css中的图片 htmlContent = this.ReplaceBackgroundUrl(htmlContent, this.PageUrl, dirConfig, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, true, dic); #endregion //确定异步下载都已经下载完成,将html内容中的占位符替换为资源下载完成后对应的相对路径 htmlContent = this.ReplacePlaceHolder(htmlContent, dic); return(FileUtility.SaveText(Path.GetFullPath(dirConfig.HtmlDirPath + "\\" + fileName), htmlContent, this.encode)); }
/// <summary> /// 操作一段html文本或者css文本,将其中使用样式background:url(...)指定的图片下载到本地,并更改路径 /// </summary> /// <param name="content">一段html或者css文本</param> /// <param name="cssUrl">css文件的url,如果是内嵌css则此url为css所在页面的url</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载图片存放的目录</param> /// <param name="async">是否异步下载</param> /// <param name="dic">记录异步下载信息的字典</param> /// <returns>返回替换后的文本</returns> internal string ReplaceBackgroundUrl(string content, string cssUrl, DirConfig dirConfig, string referenceDir, string saveDir, bool async, Dictionary<string, string> dic) { //将css里面引用的图片下载到本地,并且然后替换css里的图片引用路径 content = RegexCollection.RegCssImgUrl.Replace(content, delegate(Match match) { return this.MatchUrl(match, dirConfig, cssUrl, referenceDir, saveDir, "src", delegate(string url) { //获取css里面引用图片的绝对路径,同时干掉图片url开头和结尾的引号,以免造成悲剧图片不显示的问题(例如 style="background:url("xxx.jpg");" ,如果不干掉图片地址中的引号就会出问题) return Regex.Replace(url, @"^("|'|"")|("|""|')$", ""); }, null, async, dic); }); return content; }
/// <summary> /// 替换将js、css、图片、flash等文件下载到本地后,调用此方法获取在页面中引用本地文件的路径 /// </summary> /// <param name="match">匹配到的js、css、图片、flash等标签的正则实例</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="resourceUrl">当前html页面或者css文件的url。此url用于将其内容中的相对地址转换为绝对地址并下载</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载文件存放的目录</param> /// <param name="regGroupName">指定匹配url的正则分组的组名</param> /// <param name="urlHandle">指定对匹配url(也就是href或者src)进行处理的函数回调,此回调主要对url进行一些处理(例如去引号等等)</param> /// <param name="downloadHandle">指定自定义下载处理的函数回调,此回调返回下载文件的本地路径或者占位符</param> /// <param name="async">是否异步下载</param> /// <param name="dic">记录异步下载信息的字典</param> /// <returns>返回替换后的标签字符串</returns> internal string MatchUrl(Match match, DirConfig dirConfig, string resourceUrl, string referenceDir, string saveDir, string regGroupName, MatchCallback urlHandle, MatchCallback downloadHandle, bool async, Dictionary<string, string> dic) { //文件的地址(可能是相对也可能是绝对)、文件的绝对Url地址、以及保存到本地以后的本地路径 string href, url, localPath = ""; href = match.Groups[regGroupName].Value; if (null != urlHandle) { href = urlHandle(href); } url = PathUtility.ConvertToAbsoluteHref(resourceUrl ?? this.pageUrl, href); //如果设置了根据网站url结构按对应目录存储资源,则重新设置保存目录的路径 if (dirConfig.UseWebSite) { saveDir = PathUtility.GetSaveDir(this.PageUrl, url, dirConfig.HtmlDirPath); } //如果使用异步下载 if (async) { //如果未指定异步下载函数 if (null == downloadHandle) { localPath = this.GetPlaceHolder(); //开始异步下载资源 Spider.SaveResourceAsync(url, saveDir, new Action<string>(delegate(string filePath) { lock (dic) { dic[localPath] = null == filePath ? url : PathUtility.GetRelativePath(referenceDir, filePath); } })); } else { localPath = downloadHandle(url); } if (!dic.ContainsKey(localPath)) { lock (dic) { dic.Add(localPath, null); } } }//如果使用同步下载 else { if (null == downloadHandle) { //保存文件,如果成功,则返回文件保存后的本地路 localPath = Spider.SaveResource(url, saveDir); } else { localPath = downloadHandle(url); } //如果保存失败,则引用绝对url地址 if (string.IsNullOrEmpty(localPath)) { localPath = url; } else { localPath = PathUtility.GetRelativePath(referenceDir, localPath); } } //使用localPath替换html内容中的引用路径 return match.Value.Replace(href, localPath); }
/// <summary> /// 替换将js、css、图片、flash等文件下载到本地后,调用此方法获取在页面中引用本地文件的路径 /// </summary> /// <param name="match">匹配到的js、css、图片、flash等标签的正则实例</param> /// <param name="dirConfig">目录配置的实例,从中判断是否根据url结构保存</param> /// <param name="resourceUrl">当前html页面或者css文件的url。此url用于将其内容中的相对地址转换为绝对地址并下载</param> /// <param name="referenceDir">引用图片的文件所在目录(可能是html文件所在目录,也能是css文件所在目录)</param> /// <param name="saveDir">下载文件存放的目录</param> /// <param name="regGroupName">指定匹配url的正则分组的组名</param> /// <param name="urlHandle">指定对匹配url进行处理的函数回调</param> /// <param name="downloadHandle">指定自定义下载处理的函数回调,此回调返回下载文件的本地路径或者占位符</param> /// <returns>返回替换后的标签字符串</returns> internal string MatchUrl(Match match, DirConfig dirConfig, string resourceUrl, string referenceDir, string saveDir, string regGroupName, MatchCallback urlHandle, MatchCallback downloadHandle) { return MatchUrl(match, dirConfig, resourceUrl, referenceDir, saveDir, regGroupName, urlHandle, downloadHandle, false, null); }
/// <summary> ///使用同步方式下载,将html内容保存为html文件,并将html内容中引用的图片,css,js,flash都保存到本地,然后将html内容中引用的地址都转换为相对地址 /// </summary> /// <param name="fileName">保存的文件名</param> /// <param name="ignoreScript">保存的时候是否忽略Script标签,若为true,则忽略JS</param> /// <param name="dirConfig">页面下载文件夹相关配置信息</param> /// <returns>如果下载成功,返回文件的本地路径,否则返回null</returns> public string SaveHtmlAndResource(string fileName, bool ignoreScript, DirConfig dirConfig) { string htmlContent = this.html; if (!dirConfig.CheckLegal()) { throw new SpiderException("路径配置不在统一磁盘下"); } dirConfig.CreateDir(); if (string.IsNullOrEmpty(this.pageUrl)) { throw new SpiderException("未指定当前url"); } //如果忽略JS if (ignoreScript) { htmlContent = this.FilterScript(); } #region 保存所有css和css中引用的图片 htmlContent = RegexCollection.RegCssLink.Replace(htmlContent, delegate(Match match) { //由于css文件里有可能引用图片,所以在此处需要自定义css文件下载函数,将css文件中的图片下载到本地然后替换css文件中的引用路径 return this.MatchUrl(match,dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.CssDirPath, "src", null, delegate(string cssUrl) { //css内容、css保存路径 string cssContent, cssSavePath = cssUrl; CHttpWebRequest cRequest; CHttpWebResponse cResponse; //请求css文件 cRequest = Spider.CreateRequest(cssUrl); cRequest.SetHeader("Referer", this.PageUrl); cResponse = Spider.Get(cRequest); //如果请求成功 if (cResponse.Success) { using (cResponse) { //确定css文件保存的绝对路径 cssSavePath = dirConfig.UseWebSite ? Path.GetFullPath(PathUtility.GetSaveDir(this.PageUrl, cssUrl, dirConfig.HtmlDirPath) + cResponse.GetFileName()) : Path.GetFullPath(dirConfig.CssDirPath + "\\" + cResponse.GetFileName()); //获取css内容 cssContent = cResponse.GetContent(null, false); //下载css里引用的图片,并替换css内容中图片地址的引用 cssContent = this.ReplaceBackgroundUrl(cssContent, cssUrl,dirConfig, Path.GetDirectoryName(cssSavePath), dirConfig.ImgDirPath, false, null); //将css保存到本地 cssSavePath = FileUtility.SaveText(cssSavePath, cssContent, cResponse.GetEncoding()); } } //返回保存以后的css本地路径 return cssSavePath; }); }); #endregion #region 保存所有JS htmlContent = RegexCollection.RegScriptLink.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.JsDirPath, "src", null, null); }); #endregion #region 保存所有图片 htmlContent = RegexCollection.RegImg.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, "src", null, null); }); #endregion #region 保存所有Flash htmlContent = RegexCollection.RegFlash.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.FlashDirPath, "src", null, null); }); #endregion #region 当前页面内嵌css中的图片 htmlContent = this.ReplaceBackgroundUrl(htmlContent, this.PageUrl, dirConfig, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, false, null); #endregion return FileUtility.SaveText(Path.GetFullPath(dirConfig.HtmlDirPath + "\\" + fileName), htmlContent, this.encode); }
/// <summary> ///使用异步方式下载,将html内容保存为html文件,并将html内容中引用的图片,css,js,flash都保存到本地,然后将html内容中引用的地址都转换为相对地址 /// </summary> /// <param name="fileName">保存的文件名</param> /// <param name="ignoreScript">保存的时候是否忽略Script标签,若为true,则忽略JS</param> /// <param name="dirConfig">页面下载文件夹相关配置信息</param> /// <returns>如果下载成功,返回文件的本地路径,否则返回null</returns> public string AsyncSaveHtmlAndResource(string fileName, bool ignoreScript, DirConfig dirConfig) { //当前的html内容 string htmlContent = this.html; //一个字典,key是资源地址的在html中的占位符,value是资源下载到本地的路径(如果未下载成功则是资源的url) Dictionary<string, string> dic = new Dictionary<string, string>(200); if (!dirConfig.CheckLegal()) { throw new SpiderException("路径配置不在统一磁盘下"); } dirConfig.CreateDir(); if (string.IsNullOrEmpty(this.pageUrl)) { throw new SpiderException("未指定当前url"); } //如果忽略JS if (ignoreScript) { htmlContent = this.FilterScript(); } #region 保存所有css和css中引用的图片 htmlContent = RegexCollection.RegCssLink.Replace(htmlContent, delegate(Match match) { //由于css文件里有可能引用图片,所以在此处需要自定义css文件下载函数,将css文件中的图片下载到本地然后替换css文件中的引用路径 return this.MatchUrl(match, dirConfig, this.PageUrl, dirConfig.HtmlDirPath, dirConfig.CssDirPath, "src", null, delegate(string cssUrl) { //css引用在html中的占位符 string placeHolder = this.GetPlaceHolder(); //css文件在本地的目录 string filePath; //异步下载css文件中引用图片需要的字典 Dictionary<string, string> dicPlaceCss = new Dictionary<string, string>(20); CHttpWebRequest cRequest; //请求css文件 cRequest = Spider.CreateRequest(cssUrl); cRequest.SetHeader("Referer", this.pageUrl); #region 异步下载css文件 Spider.AsyncGet(cRequest, delegate(CHttpWebResponse cResponse) { //css文件内容 string cssContent; //css文件保存路径 string cssSavePath; //如果下载成功 if (cResponse.Success) { using (cResponse) { //确定css保存的绝对路径 cssSavePath = dirConfig.UseWebSite ? Path.GetFullPath(PathUtility.GetSaveDir(this.PageUrl, cssUrl, dirConfig.HtmlDirPath) + cResponse.GetFileName()) : Path.GetFullPath(dirConfig.CssDirPath + "\\" + cResponse.GetFileName()); //获取css内容 cssContent = cResponse.GetContent(null, false); //异步下载css里引用的图片,并替换css内容中图片地址的引用 cssContent = this.ReplaceBackgroundUrl(cssContent, cssUrl, dirConfig, Path.GetDirectoryName(cssSavePath), dirConfig.ImgDirPath, true, dicPlaceCss); //确定异步下载都已经下载完成,将css内容中的占位符替换为图片下载完成后对应的相对路径 cssContent = this.ReplacePlaceHolder(cssContent, dicPlaceCss); //保存css文件,获取保存以后的本地路径 filePath = FileUtility.SaveText(cssSavePath, cssContent, cResponse.GetEncoding()); //css中的图片都下载完成并且css文件也下载完成,此处设置占位符对应的引用路径 lock (dic) { //将css文件本地路径转换为一个引用路径 dic[placeHolder] = filePath == null ? cssUrl : PathUtility.GetRelativePath(dirConfig.HtmlDirPath, filePath); } } } }); #endregion //返回占位符 return placeHolder; }, true, dic); }); #endregion #region 保存所有JS htmlContent = RegexCollection.RegScriptLink.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.JsDirPath, "src", null, null, true, dic); }); #endregion #region 保存所有图片 htmlContent = RegexCollection.RegImg.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, "src", null, null, true, dic); }); #endregion #region 保存所有Flash htmlContent = RegexCollection.RegFlash.Replace(htmlContent, delegate(Match match) { return this.MatchUrl(match, dirConfig, this.pageUrl, dirConfig.HtmlDirPath, dirConfig.FlashDirPath, "src", null, null, true, dic); }); #endregion #region 当前页面内嵌css中的图片 htmlContent = this.ReplaceBackgroundUrl(htmlContent, this.PageUrl, dirConfig, dirConfig.HtmlDirPath, dirConfig.ImgDirPath, true, dic); #endregion //确定异步下载都已经下载完成,将html内容中的占位符替换为资源下载完成后对应的相对路径 htmlContent = this.ReplacePlaceHolder(htmlContent, dic); return FileUtility.SaveText(Path.GetFullPath(dirConfig.HtmlDirPath + "\\" + fileName), htmlContent, this.encode); }