C# 爬取静态网页入门

目录

确定目标内容和目标站点

分析目标站点结构

网页获取

网页节点解析

分析天气网页结构

总结


爬虫分为两种,静态网页爬虫和动态网页爬虫,相比较于动态网页爬虫而言很简单,静态网页的爬取不需要执行如JavaScript类似的代码,只需要获取页面Html代码,并解析目标内容即可,本文介绍了静态网页爬取的基本流程。

确定目标内容和目标站点

明确需求,比如本文中需要爬取北京过去一段时间内的所有天气,首先找一个合适的网站,比如http://www.tianqihoubao.com,在该网站中,可以找到北京历史天气的站点http://www.tianqihoubao.com/lishi/beijing.html

分析目标站点结构

在浏览器中打开北京历史天气站点后,不能直接获得天气,而是获得了许多超链接,其中有指向不同时间段的天气链接,因此,需要解析这个页面以分析出目标链接。

目标站点中有两类链接,一类是目标链接,另一类是其他链接。接下来在浏览器中按F12查看网页的源代码,检查目标链接的特点,这些特点有可能是Html节点或者Html属性,总之需要找到一个特点来区分目标链接和其他链接。

Html代码中,可以看到链接的两个区别

  • 两种链接的节点层次是不一样的,目标链接中有div#content 其他链接中没有,因此可以根据节点的不同来选取链接,即选取有id属性值为content的节点;
  • 最后的<a>节点中属性href的取值是不同的,目标链接总是含有"month",而其他链接中没有,因此可以根据最后一个节点的属性href的值含有"month"来选取链接。

网页获取

位于System.Net空间下的WebClient可以方便地获取网页,主要代码如下

public static string GetHtml(string url)
{
    string res = "";
    WebClient client = new WebClient();
    Stream stream = client.OpenRead(url);
    StreamReader sr = new StreamReader(stream, Encoding.Default);
    res = sr.ReadToEnd();
    sr.Close();
    client.Dispose();
    return res;
}

网页节点解析

这里有一个大名鼎鼎的库HtmlAgilityPack来辅助我们将字符串的网页html代码生成Dom树,并且让我们可以快速方便选取Dom树的节点,以完成在上节中的思路。VS打开工具->NuGet包管理器->管理解决方案的Nuget包,从这里可以搜索HtmlAgilityPack包进行相应的安装。在使用这个库时,需要引入HtmlAgilityPack命名空间。

using HtmlAgilityPack;

接下来,采取上节中的第二种思路来解析出目标链接。

  • 选择Dom树中所有含有href属性的<a>节点,这会把所有超链接的节点都选择出来,包括目标链接和其他链接;
  • 遍历所有链接节点,检查href属性的值是否以"/lishi/beijing/month"开头,是则加入链接集合
public static List<string> ParseLink(string html)
{
    List<string> res = new List<string>();
    var doc = new HtmlDocument();
    doc.LoadHtml(html);
    var linkNodes = doc.DocumentNode.SelectNodes("//a[@href]");
    foreach (var linkNode in linkNodes)
    {
        string link = linkNode.GetAttributeValue("href", "");
        if (link.StartsWith("/lishi/beijing/month"))
        {
            res.Add(link);
        }
    }
    return res;
}

至此已经解析出该站点所有含有过去时间段的链接了,接下来需要分析每一个链接对应的具体网页的结构,从中获取天气信息。

分析天气网页结构

之前的链接http://www.tianqihoubao.com/lishi/beijing.html是一个站点链接,在上节中已经分析了具体的天气网页对应的链接集合,如http://www.tianqihoubao.com/lishi/beijing/month/201101.html

现在需要从该页面中分析出天气,和解析站点结构中的目标链接一样,在浏览器中观察Html代码,发现天气这个目标内容在一个表格中,因此我们只需要选出<tr>节点就可以,因为一个<tr>节点表示某一天的天气(天气状况、气温和风力方向)。

public static void ParseDailyWeather(string html)
{
    var doc = new HtmlDocument();
    doc.LoadHtml(html);
    var rows = doc.DocumentNode.SelectNodes("//tr");
    StringBuilder sb = new StringBuilder();
    rows.RemoveAt(0);
    foreach (var row in rows)
    {
        var cols = row.SelectNodes("td");
        foreach (var col in cols)
        {
            string temp = col.InnerText.Replace("\r\n", "").Replace(" ", "").Trim();
            sb.Append(temp + ",");
        }
        sb.Append("\r\n");
    }
    FileStream fs = new FileStream("output.csv", FileMode.Append, FileAccess.Write);
    StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding("gbk"));
    sw.WriteLine(sb);
    sw.Close();
    fs.Close();
}

最后,为了实现站点的爬取,需要一个循环来实现所有网页的爬取

public static void ParseWebsite(string url)
{
    string html = Weather.GetHtml(url);
    var links = Weather.ParseLink(html);
    foreach (var link in links)
    {
        url = "http://www.tianqihoubao.com" + link;
        html = Weather.GetHtml(url);
        Weather.ParseDailyWeather(html);
    }
}

总结

静态网页的爬取比较简单,分为以下几个步骤就可以

  • 确定内容和站点。
  • 分析站点结构。从站点结构中找出目标链接的特点,分析出所有目标链接。
  • 分析网页结构。在目标链接的网页中找出目标内容的特点,提取目标内容。

猜你喜欢

转载自blog.csdn.net/Abecedarian_CLF/article/details/82992624
今日推荐