记录一次C#爬虫记录,获取必应图片

news/2024/7/19 10:57:29 标签: c#, 爬虫, python

记录一次C#爬虫记录,获取必应图片

起因

事情是这样的,我创建了一个仓库,里面有2018年到目前为止每日的必应壁纸,在八月份的时候我看到微软有接口文档,于是写了一个服务,每天早上八点钟会获取必应壁纸(目前已经可以作为api来使用了,暂时不对外开放)
然后推送到微信上面。这个项目的地址是 https://gitee.com/Pridejoy/Bing,有兴趣的可以去看看。但是吧,这个仓库有两个问题

  • 2018年以前的壁纸没有的
  • 2018年后的壁纸没有版权说明

为了更新这个仓库,我偶然见发现一个网站里面有必应壁纸,而且免费开放,我就绝对去爬这个网站

经过

说干就干,我学的是C#,听闻python爬虫很厉害,但是0基础入门就不怎么回来,下定决心就干,我发现了一个neget包爬虫挺简单的。我分析了需要爬虫的网站。然后就开始下代码

步骤

不如授人以鱼不如授人以渔

使用的具体详情 https://www.cnblogs.com/xuliangxing/p/8004403.html

安装包 HtmlAgilityPack

如何加载Html

主要常见的有三种方式;从文件加载、从字符串加载、从网页链接加载。

// 从物理路径的文件加载
var doc = new HtmlDocument();
doc.Load(filePath);//文件路径

// 从Stream当中加载
var doc = new HtmlDocument();
doc.LoadHtml(html);

// 从网页的Url链接加载
var url = "http://www.cnblogs.com/xuliangxing/";
var web = new HtmlWeb();
var doc = web.Load(url);

以Stream对象为主的重载方法:

1public void Load(Stream stream)    ///从指定的Stream对象中加载html;2public void Load(Stream stream, bool detectEncodingFromByteOrderMarks)    ///指定是否从顺序字节流中解析编码格式3public void Load(Stream stream, Encoding encoding)    ///指定编码格式4public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)5public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)  ///缓冲区大小

以指定的物理路径为主的重载方法:

1public void Load(string path)2public void Load(string path, bool detectEncodingFromByteOrderMarks)    ///指定是否从顺序字节流中解析编码格式3public void Load(string path, Encoding encoding)    ///指定编码格式4public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)5public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)
如何精准定位到我们需要的数据

这个时候我们需要用到HtmlNodeCollection和HtmlNode这两个类,我们把Html每个标签看作一个Node,所有我们想到定位到某个标签的内容,就需要知道这个标签的相关属性。顺便说一下,HtmlNode类实现了IXPathNavigable接口,这说明了它可以通过xpath来定位数据了,如果你对解析XML格式数据的XmlDocument类了解的话,特别是使用过了SelectNodes()和SelectSingleNode()方法的人来说,对使用HtmlNode类将会很熟悉。其实Html Agility Pack内部是把html解析成xml文档格式了的,所以支持xml中的一些常用查询方式。下面通过简单示例对HtmlNode的一些主要的常用成员作简要的说明。

1.通过ID属性(或者其他属性)来选择对应的节点

通用格式:@id=‘xxxx’(id可以是其他属性等等),比如我们要定位到本文博客主页的标题和副标题内容。

 HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
 doc.LoadHtml(url)//博客主页URL
 //下面的意思是:通过属性id的值,来定位header下的blogTitle节点信息
 HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//div[@id='header']/div[@id='blogTitle']");

我们还可以不通过属性id去定位,还有通过索引去定位,如下所示,这个效果和上面是等同的:

//下面的意思是:通过索引定位,div[2]是表示根节点的第二个
 HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//div[2]/div[1]");

备注:注意路径里"//“表示从根节点开始查找,两个斜杠‘//’表示查找所有childnodes;一个斜杠’/'表示只查找第一层的childnodes(即不查找grandchild);点斜杠”./"表示从当前结点而不是根结点开始查找

2.如何获取节点文本内容

 IDNode.OuterHtml ///返回结果是:<h1><a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a></h1>
 IDNode.InnerHtml ///返回结果是:<a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a>
 IDNode.InnerText ///返回结果是:法号阿兴

3.如何获取节点属性值

假如我们上面Html数据当中,博主博客地址,在标签<div id="header">里的<a>标签里,这个时候就需要使用HtmlNode下的Attribute属性了。

string url = doc.DocumentNode.SelectSingleNode("//div[@id='header']/div[@id='blogTitle']/a").Attributes["href"].Value;

4.如何获取某个标签的所有节点

我们如果获取前面Html数据的li所有分类,这个时候需要使用方法SelectNodes了

HtmlNodeCollection uiListNodes = doc.DocumentNode.SelectNodes("//ui[@id='navList']/li")

5.如何去掉外层的html tag只留下文本内容

回到我们刚刚上面讲到的地方,用remove方法。假设要删除上文结点<a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a>,你想留下博客名称而不要的话,那你需要先得到这个Html结点,通过remove方法删除掉多余的HTML Tag假设该节点叫Node:

Node.ParentNode.RemoveChild(Node,true); 

结果

结构当然是ok的了,经过一个小时的爬虫整理上传。

https://gitee.com/Pridejoy/Bing

已经上传
2016年壁纸(366张)
2017年必应壁纸(365)
2018年必应壁纸(365张)
2019年必应壁纸(365张)
2020年必应壁纸(366张)
每一张都是精彩绝伦

等到后面会把api开放出来,可以通过情求获取壁纸,包括不同的分辨率

在这里插入图片描述
先说明下,
具体的源码 https://wwa.lanzoui.com/iXeZTv7pevi


http://www.niftyadmin.cn/n/1618563.html

相关文章

python判断字符串的编码_[转] Python 字符编码判断

转自&#xff1a;http://www.cnblogs.com/dkblog/archive/2011/03/02/1980644.html 法一&#xff1a; isinstance(s, str) 用来判断是否为一般字符串 isinstance(s, unicode) 用来判断是否为unicode 或 if type(str).__name__!"unicode": strunicode(str,"utf-8…

SQL Server创建存储过程——动态SQL

简介&#xff1a; 存储过程(stored procedure)是一组为了完成特定功能的SQL语句集合&#xff0c;经编译后存储在服务器端的数据库中&#xff0c;利用存储过程可以加速SQL语句的执行。 自定义存储过程&#xff0c;由用户创建并能完成某一特定功能的存储过程&#xff0c;存储过…

python做接口测试_python实现http接口测试

get请求 import requests url"http://apis.juhe.cn/cook/query?keyccb4d2dd3c1f0feb4788da1920d7207c&menu%E8%A5%BF%E7%BA%A2%E6%9F%BF&rn10&pn3" reponserequests.get(url) print(reponse.text) post请求 a.以表单形式提交请求数据 url"http://1…

IIS部署vue项目页面刷新404,url重写问题解决办法

这里需要用到URL重写工具 --URL Rewrite(默认没有,需要自己下载安装) 如果IIS上默认有安装Web平台安装程序&#xff0c;我们可以使用平台自动安装URL Rewrite重写工具&#xff0c;打开IIS在管理器主页中找到管理项&#xff0c;打开Web平台安装程序&#xff0c;如下图&#xff…

sql cast函数_SQL基础丨SQL函数

常用的SQL函数SQL提供了一些常用的内置函数&#xff0c;通常可以把内置函数分为四类&#xff1a;- 算术函数- 字符串函数- 日期函数- 转换函数这4类函数分别代表了算数处理、字符串处理、日期处理、数据类型转换。函数是对提取出来的数据进行操作。经常会保存一些数值&#xff…

Linq中 的 ToLookup 和 GroupBy 进行分组

ToDictionary 和ToLookUp 都是通过 key 来找到相应的键值&#xff0c; ToDictionary 转换成是键值对 关系是一一对应的关系【key值是唯一的不能重复】。 ToLookUp&#xff1a;ToLookUp类似于Dictionary<string,List>【key值可重复】 public void LookUpAndDic() {var ini…

学会python的基础操作_基础操作命令

DOCKER使用指南 Auth: 王海飞 Data&#xff1a;2018-03-20 Email&#xff1a;779598160qq.com github&#xff1a;https://github.com/coco369/knowledge 前言&#xff1a; 什么是docker 引用百度搜索结果&#xff1a;Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以…

[Net分享] 写个中间件来记录接口耗时

写接口的难免会遇到别人说接口比较慢&#xff0c;到底慢多少&#xff0c;一个接口服务器处理究竟花了多长时间&#xff0c;如果能有具体的数字来记录每个接口耗时多少&#xff0c;别人再说接口慢的时候看一下接口耗时统计&#xff0c;如果几毫秒就处理完了&#xff0c;对不起这…