技术图文:如何利用C#爬取CSDN的博客文章?

背景

大家有没有这样的体验,在 CSDN 上发现某个博主有很多干货文章,我们就想拿到这个博主以往文章的列表,在需要的时候进行查询和浏览。

如果从 CSDN 网站上用复制粘贴的方式来建立这个列表,一个是工作量很大,另一个博主更新了文章,也不会第一时间知道。

所以,我想做这样的一个工具,把自己关注的 博主 主页地址存储下来,通过程序来构建这个列表,以便在需要查询资料的时候能够方便的找到。

本次,以 爬取 “老马的程序人生” 为例,来介绍如何爬取该博主的文章列表。


技术分析

首先,我们来看一下需要爬取的网页。

CSDN blog

第一页对应的网址为:

https://blog.csdn.net/lsgo_myp/article/list/1?

第二页对应的网址为:

https://blog.csdn.net/lsgo_myp/article/list/2?

以此类推,我们就能找到要爬取的网页地址。

其次,我们来看一下网页的源代码。

源码01

从以上源代码,我们发现文章列表都包含在 article-item-box 类当中。

源码02

从以上源代码,我们发现有一篇文章的 style 属性为 display:none,该篇文章不显示,当然也不是博主写的,不清楚 CSDN 放置这篇文章的目的是什么。

对于其它的文章,在 h4 标签中包含了文章的标题和对应的url地址、在 date 类中包含了文章的发表时间、在 read-num 类的 num 类中包含了文章的阅读数。

只要我们获取到网页对应的HTML DOM树,通过相应的标签就可以得到希望的数据。


代码实现

Step01:构造存储文章的结构 CsdnDataItem

public class CsdnDataItem
{
    /// <summary>
    /// 发表时间
    /// </summary>
    public DateTime Data { get; set; }
    /// <summary>
    /// 阅读数
    /// </summary>
    public int ReadNum { get; set; }
    /// <summary>
    /// 文章标题
    /// </summary>
    public string Title { get; set; }
    /// <summary>
    /// 网址
    /// </summary>
    public string Url { get; set; }

}

Step02:获取对应网页的 HTML Dom TREE

public static IHtmlDocument GetHtmlDocument(string url)
{
    IHtmlDocument document;
    try
    {
        document = new JumonyParser().LoadDocument(url);
    }
    catch
    {
        document = null;
    }
    return document;
}

Step03:获取文章列表 List<CsdnDataItem>

public static string EntryPoint;

public static List<CsdnDataItem> GetArticle(int page)
{
    List<CsdnDataItem> result = new List<CsdnDataItem>();

    string url = EntryPoint + @"/article/list/" + page + "?";
    
    IHtmlDocument document = HtmlSpiter.GetHtmlDocument(url);
    if (document == null)
        return result;

    List<IHtmlElement> lists = document.Find(".article-item-box").ToList();

    for (int i = 0; i < lists.Count; i++)
    {
        IHtmlAttribute attribute = lists[i].Attribute("style");
        if (attribute != null
            && attribute.AttributeValue.Contains("display: none"))
            continue;

        CsdnDataItem item = new CsdnDataItem();
        
        IHtmlElement temp = lists[i].FindSingle("h4");
        item.Url = temp.FindSingle("a").Attribute("href").AttributeValue;
        
        string title = temp.FindSingle("a").InnerHtml().Trim();
        int index = title.LastIndexOf("</span>", StringComparison.Ordinal);
        if (index != -1)
        {
            title = title.Substring(index + 7).Trim();
        }
        item.Title = title;
        
        string date = lists[i].FindSingle(".date").InnerHtml().Trim();
        item.Data = DateTime.Parse(date);
        
        string rednum = lists[i].FindFirst(".read-num")
            .FindSingle(".num").InnerHtml().Trim();
        item.ReadNum = int.Parse(rednum);
        result.Add(item);
    }
    return result;
}

总结

我们来看一下具体的应用:

private void btn_Click(object sender, EventArgs e)
{
    CsdnUtility.EntryPoint = comboBoxPage.Text;
    int pageTo = integerInput1.Value;
    
    List<CsdnDataItem> lst = new List<CsdnDataItem>();
    
    for (int i = 1; i <= pageTo; i++)
    {
        List<CsdnDataItem> temp = CsdnUtility.GetArticle(i);
        if (temp.Count == 0)
            break;
        lst.AddRange(temp);
    }
    ShowInGrid(lst);
}

获取的文章列表,如下所示:

爬取结果

这些数据慢慢积累起来,就可作为构建自己知识库的基础了,是不是很有意思。

今天就到这里吧!希望对大家有用,See You!


相关图文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青少年编程备考

感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值