使用 C# 和 HTMLAgility 抓取网页

Posted

技术标签:

【中文标题】使用 C# 和 HTMLAgility 抓取网页【英文标题】:Scraping a webpage with C# and HTMLAgility 【发布时间】:2011-07-16 06:26:26 【问题描述】:

我读到htmlAgility 1.4 是抓取网页的绝佳解决方案。作为一名新程序员,我希望我能在这个项目上得到一些意见。 我这样做是作为C# 申请表。我正在使用的页面相当简单。我需要的信息被困在两个标签 <table class="data"></table> 之间。

我的目标是将Part-NumManu-NumberDescriptionManu-CountryLast ModifiedLast Modified By 的数据拉出页面并将数据发送到SQL 表。

一个转折点是,还有一张PNG 的小图片也需要从src="/partcode/number 中抓取。

我没有任何可以运行的完整代码。我认为这段代码会告诉我我是否朝着正确的方向前进。即使进入调试,我也看不出它有什么作用。有人可能会在这方面为我指出正确的方向。越详细越好,因为很明显我还有很多东西要学。

谢谢你,我将不胜感激。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using System.Xml;

namespace Stats

    class PartParser
    
        static void Main(string[] args)
        
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml("http://localhost");
            //My understanding this reads the entire page in?
            var tables = doc.DocumentNode.SelectNodes("//table");
            // I assume that this sets up the search for words containing table
        
        catch (Exception ex)
        
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
            Console.ReadKey();    
        
    

网页代码是:

<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
        <title>Part Number Database: Item Record</title>
        <table class="data">
            <tr><td>Part-Num</td><td ></td><td>
            <img src="/partcode/number/072140" /></td></tr>
            <tr><td>Manu-Number</td><td ></td><td>
            <img src="/partcode/manu/00721408"  /></td></tr>    
            <tr><td>Description</td><td></td><td>Widget 3.5</td></tr>
            <tr><td>Manu-Country</td><td></td><td>United States</td></tr>    
            <tr><td>Last Modified</td><td></td><td>26 Jan 2009,  8:08 PM</td></tr>    
            <tr><td>Last Modified By</td><td></td><td>Manu</td></tr>
        </table>
    <head/>
</html>

【问题讨论】:

如果您想要使用您提供的 HTML 代码的工作代码,请查看我的答案。 【参考方案1】:

开头部分已关闭:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml("http://localhost");   

LoadHtml(html) 将一个 html 字符串加载到文档中,我想你想要这样的东西:

HtmlWeb htmlWeb = new HtmlWeb();
HtmlDocument doc  = htmlWeb.Load("http://***.com");

【讨论】:

【参考方案2】:

一个工作代码,根据您提供的 HTML 源代码。它可以被分解,我不检查 null 值(在rowscellscase 中的每个值)。如果您的页面位于 127.0.0.1 中,则可以使用。只需将其粘贴到 Console ApplicationMain 方法中并尝试理解它。

HtmlDocument doc = new HtmlWeb().Load("http://127.0.0.1");    

var rows = doc.DocumentNode.SelectNodes("//table[@class='data']/tr");
foreach (var row in rows)

    var cells = row.SelectNodes("./td");
    string title = cells[0].InnerText;
    var valueRow = cells[2];
    switch (title)
    
        case "Part-Num":
            string partNum = valueRow.SelectSingleNode("./img[@alt]").Attributes["alt"].Value;
            Console.WriteLine("Part-Num:\t" + partNum);
            break;
        case "Manu-Number":
            string manuNumber = valueRow.SelectSingleNode("./img[@alt]").Attributes["alt"].Value;
            Console.WriteLine("Manu-Num:\t" + manuNumber);
            break;
        case "Description":
            string description = valueRow.InnerText;
            Console.WriteLine("Description:\t" + description);
            break;
        case "Manu-Country":
            string manuCountry = valueRow.InnerText;
            Console.WriteLine("Manu-Country:\t" + manuCountry);
            break;
        case "Last Modified":
            string lastModified = valueRow.InnerText;
            Console.WriteLine("Last Modified:\t" + lastModified);
            break;
        case "Last Modified By":
            string lastModifiedBy = valueRow.InnerText;
            Console.WriteLine("Last Modified By:\t" + lastModifiedBy);
            break;
    

【讨论】:

感谢这个例子,它教会了我更多关于使用 html 敏捷性的知识。如果您对挑战感兴趣,我还有另一个页面,我正在努力从中获取数据,但没有典型的布局。我很想看看你会如何处理这种情况。 @JRB 好吧,我建议您先自己尝试一下,如果您在使其工作时遇到问题,请将其作为问题和您尝试做的事情发布,我们会尽力帮助您。

以上是关于使用 C# 和 HTMLAgility 抓取网页的主要内容,如果未能解决你的问题,请参考以下文章

C# 网页图片采集

java爬虫怎么抓取登陆后的网页数据

为啥我用Burpsuit抓取虚拟机的包抓不到?

用 C# 抓取 JavaScript 生成的网页

使用 C# 抓取网页(html)

C#使用Selenium+PhantomJS抓取数据