最近因朋友需要在研究如何从网站上爬小说,说到爬,很多人首先想到的是Python,但是因为没有用过Python,加上时程比较紧,就直接使用C#。
其原理也很简单,就是利用HttpWebRequest对象从网站获取HTML数据包再解析

HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(httpURL); httpReq.Method = "GET"; httpReq.ContentType = "text/html;charset=utf-8"; HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse(); HttpWebRequest htt
实际操作过程中发现有些问题,特意记录下
1、返回的HTML数据包是乱码,这个问题有两种解法,首先是要确保StreamReader的编码格式与网站URL的一致,如下
respStreamReader = new StreamReader(respStream, Encoding.UTF8);
另外就是要看服务器传回的流是否使用了gzip方法压缩,如果用了gzip方法压缩,则要用解压才行
string header = httpResp.GetResponseHeader("Content-Encoding"); StreamReader respStreamReader; if (header == "gzip") { respStreamReader = new StreamReader(new GZipStream(respStream, CompressionMode.Decompress), Encoding.UTF8); }
2、有些网站可能是为了防止别人下载内容,做了一些限制,比如不允许连续的下载,因此可以在下载一章之后暂停1000毫秒再执行。
var t = DateTime.Now.AddMilliseconds(seconds); while (DateTime.Now < t) Application.DoEvents();
3、HttpWebRequest的GetResponse或GetRequestStream偶尔超时,设置System.Net.ServicePointManager.DefaultConnectionLimit = 50;具体参照链接
4、部分网站故意打乱各章节的顺序 ,如https://www.aixs.org/xs/69/69337/,你下载下来的html文件各章节完全是乱的,但是在网站上显示却是正常的,原因是网站在运行时执行了特定的js重新更新章节顺序,这一招防下载也挺厉害,不过也不是没有解。
js代码如下
<script type="text/javascript"> var odiv=document.getElementById('listsss') var aDiv=odiv.getElementsByTagName('div') //var aDiv = document.getElementsByTagName('p'); var arr = []; for(var i=0;i<aDiv.length;i++) { arr.push(aDiv[i]); } arr.sort(function(a,b){return a.getAttribute('data-id') - b.getAttribute('data-id')}); for(var i=0;i<arr.length;i++) { odiv.appendChild(arr[i]); } var flag = true; function daoxu() { if (flag) { document.getElementById("xianshi").innerHTML = '正序显示'; flag = false; } else { document.getElementById("xianshi").innerHTML = '倒序显示'; flag = true; } if(!arrs){ var arrs = document.querySelectorAll("#chapter"); } for (var i = arrs.length - 1; i > -1; i--) { document.querySelector("#listsss").appendChild(arrs[i]); } } </script>