一小时掌握:使用ScrapySharp和C#打造新闻下载器

亿牛云

引言

爬虫技术是指通过编程的方式,自动从互联网上获取和处理数据的技术。爬虫技术有很多应用场景,比如搜索引擎、数据分析、舆情监测、电商比价等。爬虫技术也是一门有趣的技术,可以让你发现网络上的各种有价值的信息。

本文将介绍如何使用ScrapySharp和C#语言,打造一个简单的新闻下载器,可以从指定的新闻网站上抓取新闻标题、摘要、正文、作者、发布时间等信息,并保存到本地文件中。本文的目的是让你在一小时内掌握ScrapySharp和C#的基本用法,以及爬虫技术的基本原理和技巧。

ScrapySharp和C#的介绍

ScrapySharp是一个基于.NET的爬虫框架,它提供了一系列的类和方法,可以方便地实现爬虫的功能,比如发送请求、解析响应、提取数据、保存数据等。ScrapySharp的核心类是ScrapingBrowser,它模拟了一个浏览器的行为,可以执行JavaScript、处理Cookie、设置代理等。ScrapySharp还支持CSS选择器和XPath语法,可以灵活地定位网页中的元素。

C#是一种面向对象的编程语言,它是.NET平台的主要语言,可以运行在Windows、Linux、Mac等操作系统上。C#语言简洁、强大、高效,拥有丰富的类库和工具,可以开发各种类型的应用程序,包括桌面应用、网站、移动应用、游戏等。C#还支持多线程编程,可以充分利用CPU的资源,提高程序的性能。

新闻下载器的设计

本文的新闻下载器的设计思路如下:

  • 首先,定义一个News类,用来存储新闻的各种属性,比如标题、摘要、正文、作者、发布时间等。
  • 然后,定义一个NewsDownloader类,用来实现新闻下载器的主要逻辑,包括以下几个方法:
    • 构造方法,用来初始化ScrapingBrowser对象,设置代理、超时、用户代理等参数。
    • GetNewsUrls方法,用来从指定的新闻网站的首页上,获取所有新闻的链接,并返回一个字符串列表。
    • GetNewsContent方法,用来从指定的新闻链接上,获取新闻的内容,并返回一个News对象。
    • SaveNews方法,用来将一个News对象保存到本地文件中,文件名为新闻的标题,文件格式为txt。
    • DownloadNews方法,用来下载所有新闻,并保存到本地文件夹中,文件夹名为新闻网站的域名。
  • 最后,定义一个Program类,用来作为程序的入口,创建一个NewsDownloader对象,并调用其DownloadNews方法,传入要爬取的新闻网站的地址。

新闻下载器的代码

本文的新闻下载器的代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using ScrapySharp.Extensions;
using ScrapySharp.Network;namespace NewsDownloader
{// 定义一个News类,用来存储新闻的各种属性public class News{public string Title { get; set; } // 标题public string Summary { get; set; } // 摘要public string Content { get; set; } // 正文public string Author { get; set; } // 作者public string Time { get; set; } // 发布时间}// 定义一个NewsDownloader类,用来实现新闻下载器的主要逻辑public class NewsDownloader{private ScrapingBrowser browser; // 定义一个ScrapingBrowser对象,用来模拟浏览器的行为//亿牛云 设置爬虫代理加强版private string proxyDomain = "http://www.16yun.cn"; // 定义代理的域名private int proxyPort = 9010; // 定义代理的端口private string proxyUser = "16YUN"; // 定义代理的用户名private string proxyPass = "16IP"; // 定义代理的密码// 构造方法,用来初始化ScrapingBrowser对象,设置代理、超时、用户代理等参数public NewsDownloader(){browser = new ScrapingBrowser();browser.Timeout = TimeSpan.FromSeconds(10); // 设置超时时间为10秒browser.UserAgent = new FakeUserAgent("Chrome", 88.0); // 设置用户代理为Chrome 88.0browser.UseDefaultCookiesParser = false; // 禁用默认的Cookie解析器browser.Proxy = new WebProxy(proxyDomain, proxyPort); // 设置代理browser.Proxy.Credentials = new NetworkCredential(proxyUser, proxyPass); // 设置代理的凭证}// GetNewsUrls方法,用来从指定的新闻网站的首页上,获取所有新闻的链接,并返回一个字符串列表public List<string> GetNewsUrls(string url){List<string> newsUrls = new List<string>(); // 定义一个字符串列表,用来存储新闻的链接try{WebPage homePage = browser.NavigateToPage(new Uri(url)); // 使用ScrapingBrowser对象访问新闻网站的首页,并获取WebPage对象HtmlNode homeNode = homePage.Html; // 从WebPage对象中获取HtmlNode对象,表示网页的HTML文档IEnumerable<HtmlNode> newsNodes = homeNode.CssSelect("a[href*='/news/']"); // 使用CSS选择器,从HtmlNode对象中获取所有包含'/news/'的a标签的HtmlNode对象,表示新闻的链接foreach (HtmlNode newsNode in newsNodes) // 遍历所有新闻的链接{string newsUrl = newsNode.GetAttributeValue("href", null); // 从HtmlNode对象中获取href属性的值,表示新闻的链接if (newsUrl != null && !newsUrls.Contains(newsUrl)) // 如果新闻的链接不为空,且不在字符串列表中{newsUrls.Add(newsUrl); // 将新闻的链接添加到字符串列表中}}}catch (Exception ex) // 捕获异常{Console.WriteLine("GetNewsUrls error: " + ex.Message); // 在控制台输出异常信息}return newsUrls; // 返回字符串列表}// GetNewsContent方法,用来从指定的新闻链接上,获取新闻的内容,并返回一个News对象public News GetNewsContent(string url){News news = new News(); // 定义一个News对象,用来存储新闻的内容try{WebPage newsPage = browser.NavigateToPage(new Uri(url)); // 使用ScrapingBrowser对象访问新闻的链接,并获取WebPage对象HtmlNode newsNode = newsPage.Html; // 从WebPage对象中获取HtmlNode对象,表示网页的HTML文档HtmlNode titleNode = newsNode.CssSelect("h1").FirstOrDefault(); // 使用CSS选择器,从HtmlNode对象中获取第一个h1标签的HtmlNode对象,表示新闻的标题HtmlNode summaryNode = newsNode.CssSelect("p.summary").FirstOrDefault(); // 使用CSS选择器,从HtmlNode对象中获取第一个p标签,且class属性为summary的HtmlNode对象,表示新闻的摘要HtmlNode contentNode = newsNode.CssSelect("div.article-content").FirstOrDefault(); // 使用CSS选择器,从HtmlNode对象中获取第一个div标签,且class属性为article-content的HtmlNode对象,表示新闻的正文HtmlNode authorNode = newsNode.CssSelect("span.author").FirstOrDefault(); // 使用CSS选择器,从HtmlNode对象中获取第一个span标签,且class属性为author的HtmlNode对象,表示新闻的作者HtmlNode timeNode = newsNode.CssSelect("span.time").FirstOrDefault(); // 使用CSS选择器,从HtmlNode对象中获取第一个span标签,且class属性为time的HtmlNode对象,表示新闻的发布时间if (titleNode != null) // 如果标题节点不为空{news.Title = titleNode.InnerText.Trim(); // 从HtmlNode对象中获取文本内容,并去除两端的空白字符,赋值给News对象的Title属性}if (summaryNode != null) // 如果摘要节点不为空{news.Summary = summaryNode.InnerText.Trim(); // 从HtmlNode对象中获取文本内容,并去除两端的空白字符,赋值给News对象的Summary属性}if (contentNode != null) // 如果正文节点不为空{news.Content = contentNode.InnerText.Trim(); // 从HtmlNode对象中获取文本内容,并去除两端的空白字符,赋值给News对象的Content属性}if (authorNode != null) // 如果作者节点不为空{news.Author = authorNode.InnerText.Trim(); // 从HtmlNode对象中获取文本内容,并去除两端的空白字符,赋值给News对象的Author属性}if (timeNode != null) // 如果时间节点不为空{news.Time = timeNode.InnerText.Trim(); // 从HtmlNode对象中获取文本内容,并去除两端的空白字符,赋值给News对象的Time属性}}catch (Exception ex) // 捕获异常{Console.WriteLine("GetNewsContent error: " + ex.Message); // 在控制台输出异常信息}return news; // 返回News对象}// SaveNews方法,用来将一个News对象保存到本地文件中,文件名为新闻的标题,文件格式为txtpublic void SaveNews(News news, string folder){try{string fileName = news.Title + ".txt"; // 定义文件名为新闻的标题加上.txt后缀string filePath = Path.Combine(folder, fileName); // 定义文件路径为文件夹和文件名的组合using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8)) // 使用StreamWriter对象,以UTF-8编码,覆盖模式,打开或创建文件{writer.WriteLine("标题:" + news.Title); // 写入新闻的标题writer.WriteLine("摘要:" + news.Summary); // 写入新闻的摘要writer.WriteLine("正文:" + news.Content); // 写入新闻的正文writer.WriteLine("作者:" + news.Author); // 写入新闻的作者writer.WriteLine("时间:" + news.Time); // 写入新闻的时间}}catch (Exception ex) // 捕获异常{Console.WriteLine("SaveNews error: " + ex.Message); // 在控制台输出异常信息}}// DownloadNews方法,用来下载所有新闻,并保存到本地文件夹中,文件夹名为新闻网站的域名public void DownloadNews(string url){try{Uri uri = new Uri(url); // 定义一个Uri对象,表示新闻网站的地址string folder = uri.Host; // 定义文件夹名为Uri对象的Host属性,表示新闻网站的域名if (!Directory.Exists(folder)) // 如果文件夹不存在{Directory.CreateDirectory(folder); // 创建文件夹}List<string> newsUrls = GetNewsUrls(url); // 调用GetNewsUrls方法,获取所有新闻的链接Parallel.ForEach(newsUrls, newsUrl => // 使用Parallel类的ForEach方法,对所有新闻的链接进行并行处理,提高采集效率{News news = GetNewsContent(newsUrl); // 调用GetNewsContent方法,获取新闻的内容SaveNews(news, folder); // 调用SaveNews方法,将新闻保存到本地文件中Console.WriteLine("Downloaded: " + news.Title); // 在控制台输出下载成功的新闻的标题});Console.WriteLine("Download completed!"); // 在控制台输出下载完成的提示}catch (Exception ex) // 捕获异常{Console.WriteLine("DownloadNews error: " + ex.Message); // 在控制台输出异常信息}}}// 定义一个Program类,用来作为程序的入口class Program{static void Main(string[] args){NewsDownloader downloader = new NewsDownloader(); // 创建一个NewsDownloader对象downloader.DownloadNews("https://www.bbc.com/news"); // 调用其DownloadNews方法,传入要爬取的新闻网站的地址Console.ReadKey(); // 等待用户按键}}
}

结论

本文介绍了如何使用ScrapySharp和C#语言,打造一个简单的新闻下载器,可以从指定的新闻网站上抓取新闻标题、摘要、正文、作者、发布时间等信息,并保存到本地文件中。本文的目的是让你在一小时内掌握ScrapySharp和C#的基本用法,以及爬虫技术的基本原理和技巧。

本文的技术文章和代码仅供参考,你可以根据自己的需求和兴趣,修改或扩展它们,实现更多的功能,比如添加异常处理、日志记录、数据清洗、数据分析等。希望本文能对你的学习和开发有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235928.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity组件开发--长连接webSocket

1.下载安装UnityWebSocket 插件 https://gitee.com/cambright/UnityWebSocket/ 引入unity项目&#xff1a; 2.定义消息体结构&#xff1a;ExternalMessage和包结构Package&#xff1a; using ProtoBuf; using System; using System.Collections; using System.Collections.Ge…

【java八股文】之Java基础篇

1、Java有哪几种数据类型 基本数据类型&#xff1a;byte(1字节) short&#xff08;2字节&#xff09; int&#xff08;4字节&#xff09; long&#xff08;8字节&#xff09; float&#xff08;4字节&#xff09; double&#xff08;8字节&#xff09; char&#xff08;2字节&a…

【动态规划】 【字典树】C++算法:472 连接词

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 动态规划 字典树 LeetCode472 连接词 给你一个 不含重复 单词的字符串数组 words &#xff0c;请你找出并返回 words 中的所有 连接词 。 连接词 定义为&#xff1a;一个完全由给定数组中的至少两个较短单词&#xff08;不…

DUET: Cross-Modal Semantic Grounding for Contrastive Zero-Shot Learning论文阅读

文章目录 摘要1.问题的提出引出当前研究的不足与问题属性不平衡问题属性共现问题 解决方案 2.数据集和模型构建数据集传统的零样本学习范式v.s. DUET学习范式DUET 模型总览属性级别对比学习正负样本解释&#xff1a; 3.结果分析VIT-based vision transformer encoder.消融研究消…

RTL编码(1)——概述

一、RTL级描述 RTL&#xff08;Register Transfer Level&#xff09;级&#xff1a;寄存器&#xff0b;组合逻辑&#xff0c;其功能与时序用Verilog HDL&#xff08;以下简称Verilog&#xff09;或VHDL代码描述。 RTL描述包含了同步数字电路最重要的三个特征&#xff1a;组合逻…

【Python】编程练习的解密与实战(三)

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Python | 编程解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1fa90;1. 初识Python &a…

[BJDCTF2020]ZJCTF,不过如此

题目源码&#xff1a; <?phperror_reporting(0); $text $_GET["text"]; $file $_GET["file"]; if(isset($text)&&(file_get_contents($text,r)"I have a dream")){echo "<br><h1>".file_get_contents($tex…

vscode 创建文件自动添加注释信息

随机记录 目录 1. 背景介绍 2. "Docstring Generator"扩展 2.1 安装 2.2 设置注释信息 3. 自动配置py 文件头注释 1. 背景介绍 在VS Code中&#xff0c;您可以使用扩展来为新创建的Python文件自动添加头部注释信息。有几个常用的扩展可以实现此功能&#xff0…

im6ull学习总结(三-五)freetype显示正行字

知识补充 笛卡尔坐标系 这里笛卡尔坐标系就是初高中学的直角坐标系的第一象限 lcd坐标系则不同 这两个坐标系如何转换 观察两个坐标系 点&#xff08;x,y&#xff09;的x坐标在两个坐标系中相同&#xff0c;纵坐标&#xff08;y&#xff09;存在着yV-yV V是整个屏幕的行数的像…

Mysql是怎么运行的(上)

文章目录 Mysql是怎么运行的Mysql处理一条语句的流程连接管理解析与优化存储引擎 基本配置配置文件系统变量状态变量字符集四种重要的字符集MySQL中的utf8和utf8mb4各级别的字符集和比较规则MySQL中字符集的转换排序规则产生的不同的排序结果 InnoDB存储引擎介绍COMPACT行格式介…

PostgreSQL内存浅析

体系结构 &#xff08;https://www.postgresql.fastware.com/blog/lets-get-back-to-basics-postgresql-memory-components&#xff09; &#xff08;http://geekdaxue.co/read/fcantsql/qts5is) 共享内存 linux的共享内存实现 (https://momjian.us/main/writings/pgsql/insi…

解锁前端新潜能:如何使用 Rust 锈化前端工具链

前言 近年来&#xff0c;Rust的受欢迎程度不断上升。首先&#xff0c;在操作系统领域&#xff0c;Rust 已成为 Linux 内核官方认可的开发语言之一&#xff0c;Windows 也宣布将使用 Rust 来重写内核&#xff0c;并重写部分驱动程序。此外&#xff0c;国内手机厂商 Vivo 也宣布…

如何利用ChatGPT快速生成月报?

随着每个月的结束&#xff0c;个人和团队经常需要编写月报来回顾和总结。这项任务通常消耗大量时间和精力。幸运的是&#xff0c;借助ChatGPT&#xff0c;这个过程可以变得更加简单和高效。接下来&#xff0c;我将详细介绍如何利用ChatGPT快速生成月报&#xff0c;从而帮助你节…

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BP回归基于冠豪猪优化算法[24年新…

Redis(四)事务

文章目录 事务Redis事务 vs 数据库事务常用命令总结 事务 一个队列中、一次性、顺序性、排他性执行一系列命令 官网https://redis.io/docs/interact/transactions/ Redis事务 vs 数据库事务 概述详述1、单独的隔离操作Redis的事务仅仅是保证事务里的操作会被连续独占的执行&a…

【AI视野·今日Sound 声学论文速览 第四十三期】Mon, 8 Jan 2024

AI视野今日CS.Sound 声学论文速览 Mon, 8 Jan 2024 Totally 6 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers MusicAOG: an Energy-Based Model for Learning and Sampling a Hierarchical Representation of Symbolic Music Authors Yikai Qian, Tia…

leetcode面试经典150题——50 快乐数

题目&#xff1a;快乐数 描述&#xff1a; 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变…

Element-ui图片懒加载

核心代码 <el-image src"https://img-blog.csdnimg.cn/direct/2236deb5c315474884599d90a85d761d.png" alt"我是图片" lazy><img slot"error" src"https://img-blog.csdnimg.cn/direct/81bf096a0dff4e5fa58e5f43fd44dcc6.png&quo…

【Redis】Redis面试热点

Redis 集群有哪些方案&#xff1f; 主从复制&#xff1a;解决了高并发问题 哨兵模式&#xff1a;解决了高并发&#xff0c;高可用问题 分片集群&#xff1a;解决了海量数据存储&#xff0c;高并发写的问题 主从复制 图示&#xff1a; 主从复制&#xff1a;单节点 Redis 并发…

2023 Gartner® 云数据库管理系统魔力象限发布 PingCAP 入选“荣誉提及”

近日&#xff0c;全球 IT 市场研究和咨询 公司 Gartner 发布最新报告《Magic Quadrant™ for Cloud Database Management Systems》&#xff08;云数据库管理系统魔力象限&#xff09;&#xff0c; 企业级开源分布式数据库厂商 PingCAP 入选“荣誉提及” 。前不久&#xff0c;P…