c#抓取网页数据(1.网络爬虫的基础知识,发送Http请求的方法(图) )

优采云 发布时间: 2021-11-07 20:14

  c#抓取网页数据(1.网络爬虫的基础知识,发送Http请求的方法(图)

)

  一时兴起,感觉有时候在网页上保存资源很麻烦。有没有办法输入一个网址,批量抓取对应的资源?

  需要思考的问题:

  1.如何获取网页url的html源代码?

  2.如何在浩瀚的html中匹配所需的资源地址?

  3.如何根据获取到的资源地址批量下载资源?

  4. 下载的资源一般是文件流。如何生成并保存指定的资源类型?

  需要掌握的知识:

  1.网络爬虫基础知识,发送Http请求的方法

  2.C#正则表达式的使用,主要是识别html中需要的rul URLs

  3.UnityWebRequest 文件流下载

  4.C#基本文件操作如File类和Stream类

  实施了以下子项:

  这里不介绍爬虫。互联网上其他地方有很多信息。简而言之,就是采集网页信息和数据的程序。

  第一步是发送一个Web请求,也可以说是一个Http请求。

  这与打开浏览器输入url地址然后回车的效果基本类似。网页之所以能够显示正确的信息和数据,是因为每个网页都有对应的html源代码,像很多浏览器一样,比如谷歌浏览器就支持查看网页源代码的功能。比如下面是我经常去的喵窝首页的html部分:

  

  在html源代码中,可以查看当前网页的大量隐藏信息和数据,包括大量的资源链接和样式表。值得注意的是,html源代码只有在网页完全加载后才能显示和查看,这意味着一个URL地址的web请求响应成功;当然在成功的情况下会有各种失败,比如我们经常输入rul地址后出现404提示。这是 Http 请求出错的情况。404 表示服务器没有找到请求的网页。还有许多其他类型的错误。为什么要理解这个,因为发送完Http请求后,要找到处理错误的方法或者跳过下一个任务。

  我们可以通过多种方式发送Http请求,Unity也更新了web请求的方式:(以后直接截图代码,这个插入代码的功能不能自动排序,真的很不爽)

  

  使用的主要类是UnityWebRequest,类似于之前Unity中的WWW类,主要用于文件的下载和上传。

  引入以下命名空间:

  

  UnityAction 作为参数主要用于请求结束后自动返回一个html源代码。它本质上是一个通用委托:

  

  泛型参数可以从无到多,是一个很有用的类(尤其是在协程的回调中,可以很方便的延迟参数传递)

  当然,除了Unity内置的发送web请求的方法,C#还封装了几个类,你可以随便挑一个使用,比如HttpWebRequest、WebClient、HttpClient等:

  例如:

  

  如果通过web请求成功获取到指定url地址的html源代码,则可以进行下一步。

  第二步,采集html中需要的数据信息。在这个例子中,图片的链接地址是从源代码中找到的。

  例如,可能有以下几种情况:

  

  

  

  

  总结一下,首先使用html的常用标签

  来找大部分图片,但还是有一些图片不在这些标签中。有时,即使在

  标签中的图片地址在内部链接和外部链接之间可能仍然不同。如果使用外部链接,可以直接作为合法的url地址执行,但是如果是内部链接,则必须填写域名地址,所以我们还是需要想办法识别一个正确的域名网址。

  关于如何识别和匹配上面提到的字符串内容,目前最有效的方法是正则表达式。本例中需要用到的正则表达式如下:

  1.匹配url域名地址:

  private const string URLRealmCheck = @"(http|https)://()?(\w+(\.)?)+";

  2.匹配url地址:

  private const string URLStringCheck = @"((http|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|( [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(: [0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?";

  3.匹配html

  标签中的url地址:(不区分大小写,分组

  

  是需要的url地址)

  私有常量字符串 imgLableCheck = @"

  ]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""\']?[\s\t\r\n]*(?

  

  [^\s\t\r\n""\']*)[^]*?/?[\s\t\r\n]*>";

  4. 匹配html中标签中href属性的url地址:(不区分大小写,主要用于深度检索,需要的url地址在分组中)

  private const string hrefLinkCheck = @"(?i)]*?href=([\'""]?)(?!javascript|__doPostBack)(?[^\'""\s*#]+)[^> ]*>";

  5. 指定图片类型匹配:(主要用于外链)

  私有常量字符串 jpg = @"\.jpg";

  私有常量字符串 png = @"\.png";

  关于正则表达式的具体匹配用法,网上也有很多教程,这里就不赘述了。

  给定一个html源码,下面从两个方向匹配图片,首先匹配外部链接,这里指定匹配的文件类型:

  

  以下是内链匹配,必须先匹配域名地址:

  

  有了域名地址后,就可以轻松匹配内链地址:

  

  正则表达式的使用需要引入以下命名空间:

  

  将所有的imgLinks与正则表达式匹配后,就可以依次下载图片了。

  第三步,下载并传输有效的图片url:

  

  您也可以同步下载和传输这些 URL,但这可能需要额外的最大线程数,并且更难以控制整体下载进度。

  具体传输协议如下:

  

  值得注意的是,Complete方法不是只有在下载成功时才调用,即使出现错误也需要调用,避免出现错误时自动下载自动终止的情况。正常情况下,即使发生错误,下一个文件的下载任务也会被跳过。

  最后一步是将下载的数据文件流转换为指定类型的文件并保存。这里有很多方法,下面提供了其中一种:

  

  扩张:

  有时单个html中的所有图片链接并不能完全满足我们的需求,因为html中的子链接中也可能有需要的URL资源地址。这时候可以考虑加入更深的遍历。然后需要先匹配html中的链接地址,然后获取链接地址的子html源码,这样就进行了深度匹配的循环。

  可以通过查找标签属性href 来匹配html 中的子链接。上面已经给出了这个属性的正则匹配表达式。这里只提供一层深度匹配供参考:

  

  测试:这里我们使用深度匹配,抓取jpg格式的妙我首页图片链接,下载,保存到D盘。(UI随心所欲,不用管)

  

  

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线