C#批量爬取网站验证码图片爬取网页内容(1)

xiaoxiao2021-02-28  46

前段时间师姐给了我一个C#爬图的代码,很简单有效。我查了点资料,把代码搞懂了然后简化又扩展了一下使它能够爬取网页内容。现在把代码和过程放上来供有兴趣的朋友一起探讨。

这一部分只讲如何爬验证码图片。爬取内容的部分见下一篇博客吧~

1.获取验证码图片链接

有的验证码进入网页就有,有的要在登录界面输入用户名,故意输错几次密码才能把验证码刷出来。

新浪的验证码,如图所示:

然后右击验证码图片,选择在新标签页中打开图片。

新标签页面中只有验证码图片,且每刷新一下页面就会发现验证码也变了。但是这个标签页的链接是不会变的,只是每次刷新都会随机展示一个验证码而已。这个标签页的链接就是我们要找的!!!

复制这个链接,比如新浪的是:https://login.sina.com.cn/cgi/pin.php?r=1523262272227&lang=zh&type=hollow

2.C#控制台编程

其实编窗体程序也可以,这里简化一下,跑个控制台程序就好。

VS->文件->新建->项目->visual c#->控制台应用程序,项目命名随意啦,我命名的是csharpconsole。先加入三个命名空间Net 、Web和IO,如下图所示。

3.编写DownloadPicture函数

传入的参数为验证码链接,验证码保存的路径,要下载的验证码的数量。创建一个http请求,得到回应,如果http响应的contentype类型不是文本文件类型,那就把它在SaveBinaryFile中保存为png格式,就是我们要的验证码图片。要下载多少张,就循环多少次。

public static bool DownloadPicture(string picUrl, string savePath, int num) { bool value = false; WebResponse response = null; for (int i = 0; i < num; i++) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(picUrl); response = request.GetResponse(); if (!response.ContentType.ToLower().StartsWith("text/")) //如果该文件不是文本文件 value = SaveBinaryFile(response, savePath, i); } finally { if (response != null) response.Close(); } } return value; }

 

相信看到这里的你也许会有疑惑,为什么在这里不以text/开头就是我们要的图片文件呢?

是这样哒,我们向服务器发送了一个http请求,服务器接受请求并返回http响应,这个响应中包含的

 

Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。如果未指定content-type,默认为text/html。放张图:

 

 

 

 

一般来讲,由本文中第一条的方法得到的链接中只包含验证码图片,如果向该链接发送http请求,得到的响应一般都是以image/开头。可能是image/jpeg,也可能是image/png等等。但也有比如sogou的验证码,它的content-type类型就为空。如果直接按照是否以image开头进行匹配的话,sougou的验证码是下不下来的。不信的话你可以试试,喏,放个sougou的链接给你:https://account.sogou.com/captcha?token=dd98ba705e21d35cf9223ef254e78b38&t=1521161194532

所以,就写了如果不以text/开头,那就把它保存下来,而不是如果以image/开头就把它保存下来。

 

4.编写SaveBinaryFile函数

这个函数呢,就是实现把web页面上的内容保存到本地文件。我们链接中的内容就是验证码图片呀,保存到本地为png格式就好啦。具体的内容,我都在代码里写了注释。

private static bool SaveBinaryFile(WebResponse response, string savePath, int index) { bool value = false; byte[] buffer = new byte[1024];//缓冲区临时保存二进制文件的内容 Stream outStream = null; Stream inStream = null; try { if (File.Exists(savePath)) File.Delete(savePath); string savefile = savePath + (index).ToString() + ".png"; outStream = System.IO.File.Create(savefile);//写入本地文件的输出流 inStream = response.GetResponseStream();//读取web页面的输入流 int l; do //通过循环读取web文件的内容并写入到本地文件 { l = inStream.Read(buffer, 0, buffer.Length); //在instream流中,从0开始读buffer.Length个字节存储到buffer中,返回的值为读取的字节数。如果达到流结尾,则返回0 if (l > 0) outStream.Write(buffer, 0, l);//将从0开始的l个字节从 buffer 复制到当前outstream流中 } while (l > 0); value = true; } finally { if (outStream != null) outStream.Close(); if (inStream != null) inStream.Close(); } return value; }

5.编写main函数

这就非常简单啦,只需要在main函数里调用DownloadPicture函数就OK啦。

static void Main(string[] args) { DownloadPicture("https://login.sina.com.cn/cgi/pin.php?r=1523262272227&lang=zh&type=hollow", "E:\\sina-captcha\\", 100); //1中找的链接,图片的存储地址,图片个数 }

我这里用新浪的验证码给大家示例,下载个100张吧,很快的。

达浪达浪达浪给大家展示一下结果吧:

(有说的不对的地方,或者可以改进的地方,欢迎大家讨论指正。感兴趣的朋友也可以照这个步骤自己来一遍哟)

唉,写博客是一件比较累人的事情,想我上一篇博客说要配图一直没配,代码还贼长,导致它不是一篇好博客。

 

 

 

转载请注明原文地址: https://www.6miu.com/read-2623370.html

最新回复(0)