1、第一步: 我们先复制一份原来的规则 做模板 比如说我今天演示的采集站点是 我爱读书网 52dsw.net 这个小说站点那么我就把我复制的那份做模板的规则 命名为 52dsw.xml 这个主要是便于记忆
2、第二步: 我们运行 采集器里的规则管理工具 打开后加载刚刚我们命名为 52dsw.xml的这个XML文件
3、第三步: 开始正式编写规则了1. RULEID(规则编号) 这个任意2. GetSiteName(站点名称) 这里我们写 我爱读书网3. GetSiteCharset(站点编码) 这里我们打开 www.52dsw.net 查找 charset= 这个 =号后面的就是我们需要的站点编码www.52dsw.net 我们查到的 编码是 gb23124. GetSiteUrl(站点地址) 这个就不用我说了吧 写入 http://www.52dsw.net/5. NovelSearchUrl(站点搜索地址) 这个地址的获得 得按照每个网站程序的不同而言 不过呢有个通用的方法就是 通过抓包来获得自己想要的内容虽然说是通过抓包来获得但是 怎么就知道获得的就是我们想要的呢 看我操作 首先我们运行封包工具 选择 IEXPLORE.EXE 这个进程 最好是你只开一个网站也就是你只 打开了 你要想编写规则的那个网站 确保进程里只有一个IEXPLORE.EXE这个进程 这里我们 我们可以 看到提交的地址是 /book/search.aspx 我们来组合一下 得到的地址 是 http://www.52dsw.net/book/search.aspx而提交 内容的代码是SearchKey=%C1%AB%BB%A8&SearchClass=1&SeaButton.x=26&SeaButton.y=10 但是对于我们有用的是 SearchKey=%C1%AB%BB%A8&SearchClass=1 这一段 这里获得的这段 将在NovelSearchData(搜索提交内容) 这里用到 把这段改成我们想要的代码就是 把这一段%C1%AB%BB%A8 替换成 {SearchKey} 这个 表示搜索提交的内容 完整的代码是 SearchKey={SearchKey}&SearchClass=1然后我们测试下是否正确 经过测试 我们获得的内容是正确的 6. NovelListUrl(站点最新列表地址) 这个我就不说了 因为这些 每个站点的不同 这个就需要自己去找了 我爱读书网 的是 http://www.52dsw.net/top/lastupdate_1.html7. NovelList_GetNovelKey(从最新列表中获得小说编号此规则中可以同时获得书名 获得书名是在手动模式的时候用到 如果你要用手动模式 那么必须获得书名 否则 手动模式将会无法使用)我们 打开 http://www.52dsw.net/top/lastupdate_1.html 这个地址 查看源文件我们编写这个规则的时候 找到想要获得的内容所在的地方 比如 我们打开地址 看到 想要获得的内容的 第一本小说的 名字是 立地成魔 我们在源文件里面找到 莫伦特传 <ul><li class="li1"> <a target=_blank href="/Book/LN/131.html" >奇幻</a></li><li class="li2"><a target=_blank href="/html/book/130/150557/List.shtm" ><font color="#006699">[目录]</font></a> <a href="http://www.52dsw.net/Book/150557/Index.html" target="_blank"><font color="#006633">莫伦特传</font></a></li><li class="li3"><a href="/html/book/130/150557/3946236.shtm" target="_blank">第一卷 第八章 黑暗崛起</a></li><li class="li4">11月27日</li><li class="li5"><a href="/Author/WB/150557.html" target="_blank">巨龙之瞳</a></li><li class="li6">连载 </li></ul>我们编写规则用到的代码其实也不是很多 我编写规则的原则是能省则省 也就是说代码 越短越好除非万不得已 一般精短一些比较好 好了不废话了 在这个规则里面 我们需要用到的是 <a href="http://www.52dsw.net/Book/149539/Index.html" target="_blank"><font color="#006633">立地成魔</font></a>我们将这段改下 <a href="http://www.52dsw.net/Book/(\d*)/Index.html" target="_blank"><font color="#006633">(.+?)</font></a> 其中 (\d*) 表示编号 (.+?) 表示 小说名 经过测试 正确8. NovelUrl(小说信息页地址) 这个很容易 我们随便点开一本小说 就能知道了 比如说 http://www.52dsw.net/Book/150557/Index.html 这本小说 我们可以看到的 我们改下 将里面的 150557 换成 {NovelKey} 一般情况表示小说编号 http://www.52dsw.net/Book/{NovelKey}/Index.html9. NovelErr(小说信息页错误识别标记) 这个 一般是 http://www.52dsw.net/Book/149539/Index.html 吧 中间的 那个 编号随意改变下 比如 http://www.52dsw.net/Book/15055799/Index.html 这样我们获得的错误标记就是 未找到该编号的书籍信息! 10. NovelName(获得小说名称正则) 我们随便打开一本小说 http://www.52dsw.net/Book/149539/Index.html 查看源代码 获得小说名称 这个我们可以从固定模式着手 比如我们刚才打开的 立地成魔 这本小说 我们看到他的固定小说名格式是 《立地成魔》 那我们在源代码里 找到 《立地成魔》 这个 我们得到的内容是 <div id="CrBookTitle"><span class="booktitle">《立地成魔》</span></div> 这一段 我们改下 <div id="CrBookTitle"><span class="booktitle">《(.+?)》</span></div> 下面的 NovelAuthor(获得小说作者) LagerSort(获得小说大类) SmallSort(获得小说大类) NovelIntro(获得小说简介) NovelKeyword(获得小说主角(关键字)) NovelDegree(获得写作进程)NovelCover(获得小说封面) 这些呢 我就不演示了 这些跟上面的那个获得小说名 方法是一样的 也就所谓的一通百通 这里有些时候获得的内容里面有些不想用到的 因为格式不固定有些内容只能先获得然后在用过滤功能 过滤掉 过滤的用法 在后面有说11. NovelInfo_GetNovelPubKey(获得小说公众目录页地址)这个的地址获得跟上面的一样的方法 这里我就不说明了 12 PubIndexUrl(公众目录页地址) 这个我说明一下 这个的用法 这个一般是在 知道 采集目标站的动态地址的时候用到 如果不知道对方动态地址的话 就在这个里面写入{NovelPubKey} 如果 知道动态路径比如说 http://www.52dsw.net 这个站的没本小说的章节目录的动态地址是 http://www.52dsw.net/Book/149539/Index.aspx 那么 PubIndexUrl 这个的规则就是 http://www.52dsw.net/Book/{NovelKey}/Index.aspx13. PubVolumeSplit(分割分卷) 这个分割分卷 有写地方需要注意到 如果分割分卷的正则没对 那么有可能 对于下面的 获得章节名那些有很大的影响 这里 我们获得 分割部分的代码呢 按我的经验呢 是找到第一个 分卷 跟下面的分卷 查看他们的共同处 在我们分析 http://www.52dsw.net/html/book/130/149539/List.shtm 这个目录章节里面的源代码 可以看出他们有个共同点 拿这一段来说明下 </ul><div id="feiku_e_n_d"></div> <div id="mmuu88">力量的追求 </div><ul>从这里我们可以看到他的共同点 是 </ul><div id="feiku_e_n_d"></div> 我们吧他改下改成正则格式 </ul>\s*<div id="feiku_e_n_d"></div>其中的\s* 表示 匹配 与任何白字符匹配,包括空格、制表符、分页符等 也就是说 在 </ul> 与 <div id="feiku_e_n_d"></div> 之间 不管有多少个空格 都可以用 \s* 来表示 14 . PubVolumeName(获得分卷名) 想要获得准确的分卷名 必须在上面的 分割部分的正则必须正确一般情况下 分割部分 跟 分卷名是在一块的 上面我们说明分割部分用到的 </ul><div id="feiku_e_n_d"></div> <div id="mmuu88">力量的追求 </div><ul> 这一段 大家如果有注意看到的话 会发现 里面有 我们在这一步里面要获得的分卷名我们 改下代码 <div id="mmuu88">(.+?)</div>\s*<ul> 我们测试下 正常获得分卷 但是有 这些 我们一般在 过滤规则里面过滤掉就行了 15. PubChapterName(获得章节名) 这个我们拿一段来说明<li><a title="更:2008-10-24 12:58:00 更:3264" href="3859084.shtm">强悍的驯服方法</a></li> 对于这种里面有 时间 日期 更新字数什么的 我们直接忽略 因为这些不是我们要获得的内容 这个我们可以用 .+? 来表示 有些人就问了 为什么我这里没用() 括起来呢 这里我跟大家说下 我们获得的内容是()里面的内容 如果不是你想要的内容但是写规则的时候又必须用到的 我们 可以吧表达式稍微改下就可以了 好了 我们吧 上面的那一段 改下 改成表达式 <li><a title="更.+?更.+?" href="\d*.shtm">(.+?)</a></li>正常获得内容 这个大家是不是看着这个规则有些别扭 这个是因为 中间有换行符导致的 我没改下代码我们用\s* 来表示N个换行符 我们改后的代码是<li><a title="更.+?\s*更.+?" href="\d*.shtm">(.+?)</a></li> 现在是不是好些了 经过测试 也一样正常获得内容 说明规则无问题 16. PubChapter_GetChapterKey(获得章节地址(章节编号)) 这里说明下 这个里面的章节编号是在下面的 PubContentUrl(章节内容页地址)用到 一般式知道目标站的动态地址 静态地址一般用不到 在不知道目标站的动态地址 那么 这里 我们需要获得的 是 章节地址 分析得到 <li><a title="更.+?更.+?" href="(\d*.shtm)">(.+?)</a></li> 这里既然是获得章节地址 那为什么我们还有用到 章节名的呢 这个说下 主要就是为了避免获得的章节名跟 获得的章节地址不匹配 这里在说下章节编号 的写法 其实并不麻烦只需要稍微改下就行了 <li><a title="更.+?更.+?" href="(\d*).shtm">(.+?)</a></li> 改成这样就可以了 我们测试下看看 看到了吧 这样改下就是获得编号了 这个获得的编号 只能在 知道目标站动态地址的情况下采有用到17. PubContentUrl(章节内容页地址) 上面的获得章节地址里面有说明 这个是在知道目标站的动态地址的情况下 用到 因为一般静态地址用不到 这里我拿 http://www.52dsw.net/html/book/149539/3790336.ASPX 这个来说明下 该怎么用 其中的 149539 这个是 小说编号 这里我们用 {NovelKey} 替代 3790336 这个 就是在 PubChapter_GetChapterKey 里面获得的 章节编号 我们用 {ChapterKey} 替代组合一下 就是 http://www.52dsw.net/html/book/{NovelKey}/{ChapterKey}.ASPX 这个就是我们的动态章节地址了 !!!记住 前提是 知道对方的动态地址 !!! 如果不知道对方的动态地址 那么我们在 PubContentUrl(章节内容页地址) 这里写的内容就是 {ChapterKey} 18. PubContentText(获得章节内容) 这个获得方法同于 获得章节名的那些 这个就不说明了二..好了现在我们说明下 过滤的用法 这个很容易 何谓过滤 过滤就是说剔除你不想要到的内容一般用到过滤的几个地方是 简介 章节名 分卷名 和获得的小说章节内容不过章节内容这个 有 一个替换功能 简介 章节名 分卷名 这几个暂时没有替换规则比如说 我们获得的分卷名为 正文(www.52dsw.net) 但是呢我们在获得分卷的时候只想获得 正文 这两个字 那么我们这里就用到了过滤 过滤的格式是 过滤的内容|过滤的内容 每个过滤内容中间用|来分开 简介 章节名 的过滤 跟 分卷名一样 比如说 我们获得作者名的时候 获得的内容里面有段多余的内容<li class="l5">书籍作者</li><li class="l6"><a href="/Author/WB/149539.html">聚散随风</a></li>因为他的这个 <a href="/Author/WB/149539.html"> 有些的有 有些的没有 所以我们暂时不管 直接用书籍作者</li>\s*<li class="l6">(.+?)</li> 先获得想要的内容 从规则看来我们获得的内容是 <a href="/Author/WB/149539.html">聚散随风</a> 这一段 我们在这一段里面想保留的内容是 聚散随风 我们来吧 <a href="/Author/WB/149539.html"> 跟 </a> 加入过滤规则里 </a> 这个因为是固定的 所以直接加上就行了 <a href="/Author/WB/149539.html"> 这个是变动的 我们吧他也改下 改成正则格式 <a href="/Author/WB/\d*.html">这样就行了 我们加上过滤 <a href="/Author/WB/\d*\.html">|</a> 内容就是这样 现在说下 章节内容的 替换 章节内容替换规则每行一个替换,格式如下需要替换的内容♂替换结果<div.+?> 这个表示过滤<div.+?>♂<br> 这个表示替换比如说 feiku 这个站 里面有个地字他是用的图片 我们该怎么办呢 这里我们用替换来处理<img src="http://www.52dsw.net/images/di.gif" />♂地其他的替换类似 <a href="/Author/WB/149539.html">♂替换的内容替换 只在章节内容 里才有用 这个是章节内容专用的
4、有些人又问了 为什么我采集某个站 为什么老出现空章节呢 这个出现可能空章节的原因 这个 有可能是 目标站正好重启网站 你的采集IP被封 等等...这里我要说明的 出现空章节的是 因为图片章节引起的缘故 采集器的采集内容的操作程序 是 先检查你采集的章节是否是图片章节 如果你的PubContentImages(章节内容中提取图片) 的正则不正确 没有获得 图片章节内容的话 就会 检查你的采集文字内容 PubContentText(获得章节内容)这个里面的正则的匹配 如果 PubContentImages(章节内容中提取图片) 跟 PubContentText(获得章节内容) 都没有匹配的内容 那么就出现了上面我们说的空章节的原因好了 规则写好了 我们来测试下 规则是否能够正常获得想要获得的内容测试显示 我们写的规则能够正常的获得想要的内容
5、附上我爱读书网采集规则供大家参考:<?xml version="1.0"?><RuleConfigInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <RuleVersion> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>RuleVersion</RegexName> </RuleVersion> <RuleID> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>22</Pattern> <RegexName>RuleID</RegexName> </RuleID> <GetSiteName> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>http://www.52dsw.net/</Pattern> <RegexName>GetSiteName</RegexName> </GetSiteName> <GetSiteCharset> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>gbk</Pattern> <RegexName>GetSiteCharset</RegexName> </GetSiteCharset> <GetSiteUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>http://www.52dsw.net/</Pattern> <RegexName>GetSiteUrl</RegexName> </GetSiteUrl> <NovelSearchUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>NovelSearchUrl</RegexName> </NovelSearchUrl> <NovelSearchData> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>NovelSearchData</RegexName> </NovelSearchData> <NovelSearch_GetNovelKey> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>NovelSearch_GetNovelKey</RegexName> </NovelSearch_GetNovelKey> <NovelListUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>http://www.52dsw.net/list/0.html</Pattern> <RegexName>NovelListUrl</RegexName> </NovelListUrl> <NovelList_GetNovelKey> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td class="odd"><a href="http://www.52dsw.net/book/(\d*).html">(.+?)</a></td></Pattern> <RegexName>NovelList_GetNovelKey</RegexName> </NovelList_GetNovelKey> <NovelUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>http://www.52dsw.net/book/{NovelKey}.html</Pattern> <RegexName>NovelUrl</RegexName> </NovelUrl> <NovelErr> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>未找到该编号的书籍信息</Pattern> <RegexName>NovelErr</RegexName> </NovelErr> <NovelName> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>line-height: \d*%">(.+?)</span></td></Pattern> <RegexName>NovelName</RegexName> </NovelName> <NovelAuthor> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td width="25%">作&nbsp;&nbsp;&nbsp; 者:(.+?)</td></Pattern> <RegexName>NovelAuthor</RegexName> </NovelAuthor> <LagerSort> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td width="25%">类&nbsp;&nbsp;&nbsp; 别:(.+?)</td></Pattern> <RegexName>LagerSort</RegexName> </LagerSort> <SmallSort> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td width="25%">类&nbsp;&nbsp;&nbsp; 别:(.+?)</td></Pattern> <RegexName>SmallSort</RegexName> </SmallSort> <NovelIntro> <FilterPattern>&nbsp;</FilterPattern> <Method>Match</Method> <Options>None</Options> <Pattern><span class="hottext">内容简介:</span><br />((.|\n)+?)<span class="hottext">作品关键字:</span></Pattern> <RegexName>NovelIntro</RegexName> </NovelIntro> <NovelKeyword> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>NovelKeyword</RegexName> </NovelKeyword> <NovelDegree> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td>文章状态:(.+?)</td></Pattern> <RegexName>NovelDegree</RegexName> </NovelDegree> <NovelCover> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><img src="(.+?)" border="0" width="100" height="125" align="right" hspace="5" vspace="5" /></a></Pattern> <RegexName>NovelCover</RegexName> </NovelCover> <NovelDefaultCoverUrl> <FilterPattern /> <Method>Match</Method> <Options>IgnoreCase</Options> <Pattern>nocover.jpg</Pattern> <RegexName>NovelDefaultCoverUrl</RegexName> </NovelDefaultCoverUrl> <NovelInfo_GetNovelPubKey> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><li><a class="btnlink" href="(.+?)">点击阅读</a></li></Pattern> <RegexName>NovelInfo_GetNovelPubKey</RegexName> </NovelInfo_GetNovelPubKey> <PubCookies> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>PubCookies</RegexName> </PubCookies> <PubIndexUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>{NovelPubKey}</Pattern> <RegexName>PubIndexUrl</RegexName> </PubIndexUrl> <PubIndexErr> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>这里必须填写</Pattern> <RegexName>PubIndexErr</RegexName> </PubIndexErr> <PubVolumeContent> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>PubVolumeContent</RegexName> </PubVolumeContent> <PubVolumeSplit> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><div id="tit</Pattern> <RegexName>PubVolumeSplit</RegexName> </PubVolumeSplit> <PubVolumeName> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>le">(.+?)</div></Pattern> <RegexName>PubVolumeName</RegexName> </PubVolumeName> <PubChapterName> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td class="ccss">\s*<a href="\d*.html">(.+?)</a>\s*</td></Pattern> <RegexName>PubChapterName</RegexName> </PubChapterName> <PubChapter_GetChapterKey> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><td class="ccss">\s*<a href="(\d*.html)">.+?</a>\s*</td></Pattern> <RegexName>PubChapter_GetChapterKey</RegexName> </PubChapter_GetChapterKey> <PubContentUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>{ChapterKey}</Pattern> <RegexName>PubContentUrl</RegexName> </PubContentUrl> <PubContentErr> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern>这里必须填写</Pattern> <RegexName>PubContentErr</RegexName> </PubContentErr> <PubContent_GetTextKey> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>PubContent_GetTextKey</RegexName> </PubContent_GetTextKey> <PubTextUrl> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>PubTextUrl</RegexName> </PubTextUrl> <PubContentText> <FilterPattern>&nbsp;</FilterPattern> <Method>Match</Method> <Options>IgnoreCase</Options> <Pattern><div id="content">((.|\n)+?)<div id="footlink"></Pattern> <RegexName>PubContentText</RegexName> </PubContentText> <PubContentReplace> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern /> <RegexName>PubContentReplace</RegexName> </PubContentReplace> <PubContentImages> <FilterPattern /> <Method>Match</Method> <Options>None</Options> <Pattern><[^<]*((?<=<(?:img|IMG)[^>]*(?:(?:src|SRC)(?:\s*=\s*(?:["']?))))(?:[^\s"'>]*)\.(?:jpg|gif|jpeg|bmp|png|GIF|JPG))[^>]*></Pattern> <RegexName>PubContentImages</RegexName> </PubContentImages></RuleConfigInfo>