这一章详细讲解编码过程

那么接下来就是码代码了,GO

新建NetCore WebApi项目 空的就可以

NuGet安装

Install-Package AngleSharp

或者界面安装

using。。

默认本地装有mysql或者有远程开放的mysql数据库,如何安装mysql,园区有很多文章都详细说明。

配置文件添加mysql连接 appsettings.json

{"Logging": {"LogLevel": {"Default": "Warning"}

},"AllowedHosts": "*","ConnectionStrings": {"MySql": "server=localhost;user id=root;pwd=root;database=dreaminfo;"}

}

新建实体类,这里由于比较简单,所以创建到一起,实际工作中最好不要这样,可读性较差

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel.DataAnnotations;usingSystem.ComponentModel.DataAnnotations.Schema;usingSystem.Linq;usingSystem.Threading.Tasks;namespaceWebAPI.Models

{public classDream

{

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public int Id { get; set; }public string Name { get; set; }public string Url { get; set; }public string Summary { get; set; }public string CateName { get; set; }public DateTime? CreateTime { get; set; }

}public classDreamInfo

{

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public int Id { get; set; }public int FkDreamId { get; set; }public string DreamName { get; set; }public string Name { get; set; }public string Content { get; set; }public DateTime? CreateTime { get; set; }

}

}

安装,mysql的ef支持

Install-Package Pomelo.EntityFrameworkCore.MySql

创建DBContext

usingMicrosoft.EntityFrameworkCore;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading.Tasks;namespaceWebAPI.Models

{public classMainDBContext : DbContext

{public MainDBContext(DbContextOptions options) : base(options)

{

}private stringconnection;public MainDBContext(string connection) => this.connection =connection;protected override voidOnConfiguring(DbContextOptionsBuilder optionsBuilder)

{if (!string.IsNullOrWhiteSpace(connection))

optionsBuilder.UseMySql(connection);

}public DbSet Dream { get; set; }public DbSet DreamInfo { get; set; }

}

}

配置服务

public voidConfigureServices(IServiceCollection services)

{var mysqlCon = Configuration.GetSection("ConnectionStrings:MySql").Value;

services.AddDbContext(l => l.UseMySql(mysqlCon, b => b.MigrationsAssembly("Dream"))); //跳转查看

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

}

然后是数据库迁移 ,这里使用的是codefirst,所以创建好实体类之后在实体类及EF存在的程序集执行Add-Migration命令,我这里做的比较简单,有的如果是按照框架来设计,可能实体类被设计在单独的类库里

这里是直接在webapi里面

执行之后会多出来迁移的的文件,然后执行Update-Database就可以生成数据库拉。

后期如果数据库有变更还是同样的操作

工具》打开Nuget包管理器》程序包管理控制台 选中EF所在类库

Add-Migration Update-20181123

//然后等待变更文件生成之后执行

Update-Database

然后我们看下数据库

我们刷新下,数据库和对应的表都有了。

获取页面内容

新建一个空的API控制器DreamController

然后创建获取类别数据的方法

///

///定义一个获取列表数据的方法,需要传递一个列表页面的url地址///

///

public void GetData(stringurl)

{//这个跟我之前使用的浏览器驱动类似,也是通过选择器和xpath来爬取数据//区别在于那个是模拟真人操作,这个是通过通过HttpWebRequest直接请求

var html =GetHtml(url);//创建一个(可重用)解析器前端

var parser = newHtmlParser();var document =parser.Parse(html);//找到一个页面有多少个dream信息

var mengList = document.QuerySelectorAll("#list > div.main > div.l-item > ul > li");//循环获取梦的信息

for (var i = 0; i < mengList.Length; i++)

{var meng = newDream();

meng.CateName= "人物";//名称

meng.Name = mengList[i].QuerySelector("h3 > a").TextContent;//简介

meng.Summary = mengList[i].QuerySelector("p").TextContent;//连接

meng.Url = mengList[i].QuerySelector("h3 > a").GetAttribute("href");

meng.CreateTime=DateTime.Now;

_context.Dream.Add(meng);

_context.SaveChanges();//可以单个保存,也可以获取当前页数据之后保存一次,可优化的点有很多,这里不再详细描述

}

}

但是这里获取的都是单页的数据,我们继续上一章说的,使用选择器里面的.next来寻找翻页按钮附带的连接

然后看看最后一页是什么样式

发现最后一页就没有下一页样式了,就获取不到值了,好的 那么我们开始翻页

至于翻页 还有第二种思路,就是直接获取这种类别下的最后一页的页码,然后循环就行了,似乎比较简单,我们就用这一种

完善后的方法

///

///定义一个获取列表数据的方法,需要传递一个列表页面的url地址///

///

public void GetData(string url, intpageIndex)

{var thisUrl = url + pageIndex + ".html";var html =GetHtml(thisUrl);//创建一个(可重用)解析器前端

var parser = newHtmlParser();var document =parser.Parse(html);var mengList = document.QuerySelectorAll("#list > div.main > div.l-item > ul > li");//#list > div.main > div.pagelist > a.end//获取最末页数据

if (!PageEnd.HasValue)

{var pageEnd = document.QuerySelector("#list > div.main > div.pagelist > a.end")?.TextContent;

PageEnd=Convert.ToInt32(pageEnd);

}var list = new List();for (var i = 0; i < mengList.Length; i++)

{var meng = newDream();

meng.CateName= "其他";//名称

meng.Name = mengList[i].QuerySelector("h3 > a").TextContent;//简介

meng.Summary = mengList[i].QuerySelector("p").TextContent;//连接

meng.Url = mengList[i].QuerySelector("h3 > a").GetAttribute("href");

meng.CreateTime=DateTime.Now;

_context.Dream.Add(meng);

_context.SaveChanges();

}//翻页记录页码

pageIndex++;if (pageIndex <=Convert.ToInt32(PageEnd))

{

Console.WriteLine(pageIndex+ "/" +PageEnd);//翻页完之前一直抓取

GetData(url, pageIndex);

}

}

定义接口,输出一下看看获取了多少页的数据

PageEnd是在控制器里面定义的

public classDreamController : ControllerBase

{static int? PageEnd = null;//other code

[HttpGet]public async TaskGetMengXinfo()

{

GetData("http://www.xzw.com/jiemeng/lib/renwu/", 1);returnOk(PageEnd);

}

调试走一波

可以看到这里数据其实已经拿到了,那我们就开始往数据库保存

由于是演示,我们找一个数据量较少的分类来获取 使用“其他”分类获取,调用接口,看到返回值是45

这个跟我们找到对应的数据是一样的

说明数据是ok的,我们看下数据库,dream表已经有数据了

到这里 分类数据就获取到了,其他几个分类 可以使用一个数组,循环数组拼连接获取,也可以放到后台任务慢慢执行,比如Hangfire

详细信息获取

详细信息的页面我们其实是有的,就是dream表里面的url字段,拼接上domain之后就成了详细页面的连接,我们又可以使用AngleSharp来获取数据拉。。

其实AngleSharp是对获取到的文档进行解析,里面构建了很多C#和js习惯的语法,比如

document.QuerySelector(选择器)//选择器查询单个符合条件的数据

document.QuerySelectorAll("#list > div.main > div.l-item > ul > li");获取复合条件的元素集合

获取详情页面内容,并给实体对象赋值,这里有很多可以试探的方法,大家可以尝试一下,我这个只是简单的为了完成我想要的功能。

///

///获取详情页的页面解析///

///

///

public void GetDetailData(int dreamId, stringurl)

{var html =GetHtml(url);var parser = newHtmlParser();var document =parser.Parse(html);//#wraper > div.main-wrap > div.pleft.fl > div.viewbox.box > div.sbody

var sbody = document.QuerySelector("#wraper > div.main-wrap > div.pleft.fl > div.viewbox.box > div.sbody");var dllist = sbody.QuerySelectorAll("dl");var title = sbody.QuerySelector("h2").TextContent;//标题

if (dllist.Length > 0)

{foreach (var detail indllist)

{//#wraper > div.main-wrap > div.pleft.fl > div.viewbox.box > div.sbody > dl:nth-child(4) > dt > strong

var info = newDreamInfo();

info.FkDreamId=dreamId;

info.DreamName=title;

info.Name= detail.QuerySelector("dt > strong").TextContent;

info.Content= detail.QuerySelector("dd").TextContent; ;

info.CreateTime=DateTime.Now;

_context.DreamInfo.Add(info);

_context.SaveChanges();

}

}

}

定义接口

[Route("detail")]

[HttpGet]public async TaskGetDreamInfo()

{var domain = "http://www.xzw.com";//查询出其他分类的梦数据来解析详细内容

var dreamList = _context.Dream.Where(l => l.CateName == "其他").ToList();foreach (var dream indreamList)

{

GetDetailData(dream.Id, domain+dream.Url);

}returnOk(PageEnd);

}

执行接口https://localhost:44329/api/dream/detail

这里不展示调试信息了,怕被说水内容

然后看数据库dreaminfo也有了数据

找到对应页面

到这里,数据基本都可以获取到了,其他分类可以做计划任务来获取数据

总结

对自己感兴趣的东西,可能下决心投入的时间会更长一点,共勉。

排版较乱可能影响阅读,不过内容还是能看到的。。

GitHub:https://github.com/ermpark/dream.git

database2sharp mysql_C# NetCore使用AngleSharp爬取周公解梦数据 MySql数据库的自动创建和页面数据抓取...相关推荐

  1. 爬取周公解梦数据(一)

    爬取周公解梦主页数据 1.查看周公解梦网站html 2.代码解析 url = 'https://www.zgjm.net/b/jiemeng/'headers = {"User-Agent& ...

  2. 爬取周公解梦数据(二)

    爬取周公解梦更多数据 具体解析参考爬取周公解梦数据(一) 效果 贴所有代码 import json import requests import time from bs4 import Beauti ...

  3. 用 Python selenium爬取股票新闻并存入mysql数据库中带翻页功能demo可下载

    用 Python selenium爬取实时股票新闻并存入mysql数据库中 1.分析需求 2.创建表 3.分析需要爬取的网页内容 4.python里面selenium进行爬虫操作 1.添加包 2.连接 ...

  4. python爬wos数据库,分布式爬虫困惑,如何合理安排抓取/解析/储存?

    目前情况: 一个 50 个目标网站的爬虫项目,有个 200 台的集群服务器. 爬取的内容基本上是从列表页(需要翻页)开始,抓取详情页 url,然后通过 url 抓取详情页内容. 目前架构: maste ...

  5. python爬取y80s电影并插入mysql数据库

    python爬取y80s电影并插入mysql数据库 需求分析 功能 代码实现 爬取功能 本地查询功能 运行情况 爬取功能: 查询功能: 存在问题 需求分析 1.学习中-写着玩 2.用到的库:reque ...

  6. java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...

    JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取) 发布时间:2018-05-18 16:41, 浏览次数:632 , 标签: JAVA HttpClien ...

  7. 树莓派安装python3.5_梦见树_周公解梦梦到树是什么意思_做梦梦见树好不好_周公解梦官网...

    梦见树是什么意思?做梦梦见树好不好?梦见树有现实的影响和反应,也有梦者的主观想象,请看下面由(周公解梦官网www.zgjm.org)小编帮你整理的梦见树的详细解说吧. 树主健康,树笔直挺拔,象征着人的 ...

  8. python 抓取微博评论破亿_一篇文章教会你使用Python定时抓取微博评论

    [Part1--理论篇] 试想一个问题,如果我们要抓取某个微博大V微博的评论数据,应该怎么实现呢?最简单的做法就是找到微博评论数据接口,然后通过改变参数来获取最新数据并保存.首先从微博api寻找 抓取 ...

  9. 添加多浏览器支持是什么意思_周公解梦:梦见无缘无故多了一个儿子什么意思...

    在过去那个重男轻女的时代,如果家里多一个儿子,可能这家人会笑得跟开花一样,都认为血脉是跟着男性走的,但其实血脉是男女两人的结合,传宗接代只是姓名改变而已.那么梦见无缘无故多了一个儿子是什么意思呢?下面 ...

最新文章

  1. android切图尺寸_安卓设计尺寸规范
  2. 04.设计模式-原型模式
  3. 十条nmap常用的扫描命令
  4. ​超越Transformer!AAAI 2021最佳论文:高效长序列预测模型
  5. python gis 经纬度 库_入门-Python-GIS坐标转换
  6. Java 内建函数式接口
  7. 深度学习之循环神经网络(3)梯度传播
  8. MFC开发IM-第十篇、MFC改变static text颜色
  9. 剑指offer——面试题42-2:翻转单词顺序
  10. autofs rhel7
  11. 卡卡云模板(适配彩虹发卡系统)
  12. 在线photoshop工具网站
  13. css使用rgb属性设置颜色
  14. pytorch基于GAN生成对抗网络的数据集扩充
  15. 养成良好的工作习惯(计划)
  16. 安信实验室呼吁键盘厂商申请windows徽标认证(WHQL)
  17. 带领你打开C++神秘之门--入门篇
  18. 英文年月日(日期)怎么读?
  19. Qt学习之添加游戏音效
  20. 生存还是毁灭?新物种爆发时代,企业请回答

热门文章

  1. 大盘点:抗衰界新星nmn,nmn能改善什么病症
  2. 苹果手机上运行python_【后端开发】python能在苹果手机上运行吗
  3. Excel教程(2):数据透视表-打印分页-页收尾、水印--函数简介--函数IF/IFERROR-VLookup
  4. 研究生周报(第十周)
  5. java中asList的使用
  6. [观点][幽默网文]所谓......(全集)
  7. 下个牛市,Web3世界的龙头项目PlatoFarm能否踏足山巅
  8. 日期moment与yy-mm-dd之间的转换:moment(‘00:00:00‘,‘HH:mm:ss‘)
  9. python之类成员和实例成员
  10. 秦嘉哲:11.10黄金原油震荡走高最新行情趋势分析及今日操作建议布局