遍历网页并下载 PDF
Iterate through web pages and download PDFs
我有一个代码可以抓取网页上的所有 PDF 文件并将它们下载到文件夹中。但是现在它开始报错:
System.NullReferenceException HResult=0x80004003 Message=Object
reference not set to an instance of an object. Source=NW Crawler
StackTrace: at NW_Crawler.Program.Main(String[] args) in
C:\Users\PC\source\repos\NW Crawler\NW Crawler\Program.cs:line 16
指向 foreach (HtmlNode src in ProductListPage)
中的 ProductListPage
有没有关于如何解决这个问题的提示?我试图实施 async/await 但没有成功。也许我做错了什么...
这是要完成的过程:
- 转到
https://www.nordicwater.com/products/waste-water/
- 列出部分(相关产品)中的所有 link。他们是:
<a class="ap-area-link" href="https://www.nordicwater.com/product/mrs-meva-multi-rake-screen/">MRS MEVA multi rake screen</a>
继续每个 link 并搜索 PDF 文件。 PDF 文件位于:
<div class="dl-items">
<a href="https://www.nordicwater.com/wp-content/uploads/2016/04/S1126-MRS-brochure-EN.pdf" download="">
这是我的完整测试代码:
using HtmlAgilityPack;
using System;
using System.Net;
namespace NW_Crawler
{
class Program
{
static void Main(string[] args)
{
{
HtmlDocument htmlDoc = new HtmlWeb().Load("https://www.nordicwater.com/products/waste-water/");
HtmlNodeCollection ProductListPage = htmlDoc.DocumentNode.SelectNodes("//a[@class='ap-area-link']//a");
Console.WriteLine("Here are the links:" + ProductListPage);
foreach (HtmlNode src in ProductListPage)
{
htmlDoc = new HtmlWeb().Load(src.Attributes["href"].Value);
// Thread.Sleep(5000); // wait some time
HtmlNodeCollection LinkTester = htmlDoc.DocumentNode.SelectNodes("//div[@class='dl-items']//a");
if (LinkTester != null)
{
foreach (var dllink in LinkTester)
{
string LinkURL = dllink.Attributes["href"].Value;
Console.WriteLine(LinkURL);
string ExtractFilename = LinkURL.Substring(LinkURL.LastIndexOf("/"));
var DLClient = new WebClient();
// Thread.Sleep(5000); // wait some time
DLClient.DownloadFileAsync(new Uri(LinkURL), @"C:\temp\" + ExtractFilename);
}
}
}
}
}
}
}
您使用的 Xpath 似乎不正确。我尝试在浏览器中加载网页并搜索 xpath 但没有得到任何结果。我将其替换为 //a[@class='ap-area-link']
并能够找到匹配的元素,如下图所示。
进行了一些更改以弥补您可能看到的错误。
变化
- 使用
src.GetAttributeValue("href", string.Empty)
而不是 src.Attribute["href"].Value;
。如果 href 不存在或为空,您将得到 Object Reference Not Set to an instance of an object
- 检查
ProductListPage
是否有效且不为空。
ExtractFileName
名称中包含一个 /。您想在子字符串方法中使用 + 1 来跳过 'Last / from index of)'.
- 如果任一循环中的 href 为空,则继续下一次迭代
- 已将产品列表查询从
//a[@class='ap-area-link']//a
更改为 //a[@class='ap-area-link']
。您在空的 <a>
标签中搜索 <a>
。尽管如此,如果您想以这种方式查询它,第一个检查 ProductListPage != null
是否的 IF 语句将处理错误。
HtmlDocument htmlDoc = new HtmlWeb().Load("https://www.nordicwater.com/products/waste-water/");
HtmlNodeCollection ProductListPage = htmlDoc.DocumentNode.SelectNodes("//a[@class='ap-area-link']");
if (ProductListPage != null)
foreach (HtmlNode src in ProductListPage)
{
string href = src.GetAttributeValue("href", string.Empty);
if (string.IsNullOrEmpty(href))
continue;
htmlDoc = new HtmlWeb().Load(href);
HtmlNodeCollection LinkTester = htmlDoc.DocumentNode.SelectNodes("//div[@class='dl-items']//a");
if (LinkTester != null)
foreach (var dllink in LinkTester)
{
string LinkURL = dllink.GetAttributeValue("href", string.Empty);
if (string.IsNullOrEmpty(LinkURL))
continue;
string ExtractFilename = LinkURL.Substring(LinkURL.LastIndexOf("/") + 1);
new WebClient().DownloadFileAsync(new Uri(LinkURL), @"C:\temp\" + ExtractFilename);
}
}
我有一个代码可以抓取网页上的所有 PDF 文件并将它们下载到文件夹中。但是现在它开始报错:
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=NW Crawler
StackTrace: at NW_Crawler.Program.Main(String[] args) in C:\Users\PC\source\repos\NW Crawler\NW Crawler\Program.cs:line 16
指向 foreach (HtmlNode src in ProductListPage)
ProductListPage
有没有关于如何解决这个问题的提示?我试图实施 async/await 但没有成功。也许我做错了什么...
这是要完成的过程:
- 转到
https://www.nordicwater.com/products/waste-water/
- 列出部分(相关产品)中的所有 link。他们是:
<a class="ap-area-link" href="https://www.nordicwater.com/product/mrs-meva-multi-rake-screen/">MRS MEVA multi rake screen</a>
继续每个 link 并搜索 PDF 文件。 PDF 文件位于:
<div class="dl-items"> <a href="https://www.nordicwater.com/wp-content/uploads/2016/04/S1126-MRS-brochure-EN.pdf" download="">
这是我的完整测试代码:
using HtmlAgilityPack;
using System;
using System.Net;
namespace NW_Crawler
{
class Program
{
static void Main(string[] args)
{
{
HtmlDocument htmlDoc = new HtmlWeb().Load("https://www.nordicwater.com/products/waste-water/");
HtmlNodeCollection ProductListPage = htmlDoc.DocumentNode.SelectNodes("//a[@class='ap-area-link']//a");
Console.WriteLine("Here are the links:" + ProductListPage);
foreach (HtmlNode src in ProductListPage)
{
htmlDoc = new HtmlWeb().Load(src.Attributes["href"].Value);
// Thread.Sleep(5000); // wait some time
HtmlNodeCollection LinkTester = htmlDoc.DocumentNode.SelectNodes("//div[@class='dl-items']//a");
if (LinkTester != null)
{
foreach (var dllink in LinkTester)
{
string LinkURL = dllink.Attributes["href"].Value;
Console.WriteLine(LinkURL);
string ExtractFilename = LinkURL.Substring(LinkURL.LastIndexOf("/"));
var DLClient = new WebClient();
// Thread.Sleep(5000); // wait some time
DLClient.DownloadFileAsync(new Uri(LinkURL), @"C:\temp\" + ExtractFilename);
}
}
}
}
}
}
}
您使用的 Xpath 似乎不正确。我尝试在浏览器中加载网页并搜索 xpath 但没有得到任何结果。我将其替换为 //a[@class='ap-area-link']
并能够找到匹配的元素,如下图所示。
进行了一些更改以弥补您可能看到的错误。
变化
- 使用
src.GetAttributeValue("href", string.Empty)
而不是src.Attribute["href"].Value;
。如果 href 不存在或为空,您将得到 Object Reference Not Set to an instance of an object - 检查
ProductListPage
是否有效且不为空。 ExtractFileName
名称中包含一个 /。您想在子字符串方法中使用 + 1 来跳过 'Last / from index of)'.- 如果任一循环中的 href 为空,则继续下一次迭代
- 已将产品列表查询从
//a[@class='ap-area-link']//a
更改为//a[@class='ap-area-link']
。您在空的<a>
标签中搜索<a>
。尽管如此,如果您想以这种方式查询它,第一个检查ProductListPage != null
是否的 IF 语句将处理错误。
HtmlDocument htmlDoc = new HtmlWeb().Load("https://www.nordicwater.com/products/waste-water/");
HtmlNodeCollection ProductListPage = htmlDoc.DocumentNode.SelectNodes("//a[@class='ap-area-link']");
if (ProductListPage != null)
foreach (HtmlNode src in ProductListPage)
{
string href = src.GetAttributeValue("href", string.Empty);
if (string.IsNullOrEmpty(href))
continue;
htmlDoc = new HtmlWeb().Load(href);
HtmlNodeCollection LinkTester = htmlDoc.DocumentNode.SelectNodes("//div[@class='dl-items']//a");
if (LinkTester != null)
foreach (var dllink in LinkTester)
{
string LinkURL = dllink.GetAttributeValue("href", string.Empty);
if (string.IsNullOrEmpty(LinkURL))
continue;
string ExtractFilename = LinkURL.Substring(LinkURL.LastIndexOf("/") + 1);
new WebClient().DownloadFileAsync(new Uri(LinkURL), @"C:\temp\" + ExtractFilename);
}
}