XPath 从节点内的多个标签中检索值
XPath retrieving values from multiple tags inside a node
我目前正在创建一个爬虫程序,我正处于需要抽象集合中的数据的地步,这样我就可以将它作为一行发送到数据库,既漂亮又整洁。
这是我的程序的一个片段,到目前为止它正确地转到每个页面并检索正确的对应 url
int tempflag = 0;
//linkValueList is full of sub urls previously crawled in the program
foreach (string str in linkValueList)
{
string tempURL = baseURL + str;
HtmlWeb tempWeb = new HtmlWeb();
HtmlDocument tempHtml = tempWeb.Load(tempURL);
foreach (HtmlNode node in tempHtml.DocumentNode.SelectNodes("//article[@itemprop='product']"))
{
//get the category from the linkNameList
string tempCategory = linkNameList.ElementAt(tempflag);
//grab url
string tempHref = node.GetAttributeValue("data-itemurl", string.Empty);
//grab image url
//grab brand
//grab name
//grab price
//send to database via INSERT
}
tempflag++;
}
这是我正在使用的站点代码,这是一个项目的示例,每个项目看起来都相似
<article .... itemprop="product" data-itemurl="Item's url">
<figure>
<a ....>
<img .... src="item's image source" ...>
</a>
<div ...>
<a>....</a>
</div>
</figure>
<div ...>
<a ....>
<div class="brand" itemprop="brand>Item's Brand</div>
<div class="title" itemprop="name">Item's Name</div>
</a>
<div ....>
<div class="msrp"></div>
<div class="price" itemprop="price">.99 - 9.99</div>
<span ...> ... </span>
</div>
</div>
</article>
如您所见,我已经使用 XPath 将自己置于 <article>
标记内,以获取 data-itemurl
来检索项目的 url。现在我的问题是我已经在 <article>
标签内,现在是否有一种简单的方法可以访问嵌套在其中的其他标签?
我需要找到图像 url 的 <img>
标签、品牌 <div itemprop="brand">
、商品名称 <div itemprop="name">
和 <div itemprop="price">
的价格。
正如我之前提到的,我试图一次获得所有这些信息,这样我就可以在每个循环结束时将它们作为单个插入语句查询到数据库中。
当然可以使用 node.Descendants("img")
或 node.Descendants("div").Where(d => d.Attributes.Contains("itemprop") && d.Attributes["itemprop"].Value.Equals("price"))
希望对您有所帮助。
当然可以使用另一个 XPath 在给定元素内进行查询。需要注意的是,许多人一直困扰的一件事是,永远不要以 /
开始相对 XPath,因为它会搜索整个文档,如果需要,则以 ./
开始,例如 (SelectSingleNode()
假设总是在这里找到目标元素,否则需要先检查结果是否不是 null
) :
foreach (HtmlNode node in tempHtml.DocumentNode.SelectNodes("//article[@itemprop='product']"))
{
img = node.SelectSingleNode(".//img").GetAttributeValue("src","");
brand = node.SelectSingleNode(".//div[@itemprop='brand']").InnerText.Trim();
.....
}
我目前正在创建一个爬虫程序,我正处于需要抽象集合中的数据的地步,这样我就可以将它作为一行发送到数据库,既漂亮又整洁。
这是我的程序的一个片段,到目前为止它正确地转到每个页面并检索正确的对应 url
int tempflag = 0;
//linkValueList is full of sub urls previously crawled in the program
foreach (string str in linkValueList)
{
string tempURL = baseURL + str;
HtmlWeb tempWeb = new HtmlWeb();
HtmlDocument tempHtml = tempWeb.Load(tempURL);
foreach (HtmlNode node in tempHtml.DocumentNode.SelectNodes("//article[@itemprop='product']"))
{
//get the category from the linkNameList
string tempCategory = linkNameList.ElementAt(tempflag);
//grab url
string tempHref = node.GetAttributeValue("data-itemurl", string.Empty);
//grab image url
//grab brand
//grab name
//grab price
//send to database via INSERT
}
tempflag++;
}
这是我正在使用的站点代码,这是一个项目的示例,每个项目看起来都相似
<article .... itemprop="product" data-itemurl="Item's url">
<figure>
<a ....>
<img .... src="item's image source" ...>
</a>
<div ...>
<a>....</a>
</div>
</figure>
<div ...>
<a ....>
<div class="brand" itemprop="brand>Item's Brand</div>
<div class="title" itemprop="name">Item's Name</div>
</a>
<div ....>
<div class="msrp"></div>
<div class="price" itemprop="price">.99 - 9.99</div>
<span ...> ... </span>
</div>
</div>
</article>
如您所见,我已经使用 XPath 将自己置于 <article>
标记内,以获取 data-itemurl
来检索项目的 url。现在我的问题是我已经在 <article>
标签内,现在是否有一种简单的方法可以访问嵌套在其中的其他标签?
我需要找到图像 url 的 <img>
标签、品牌 <div itemprop="brand">
、商品名称 <div itemprop="name">
和 <div itemprop="price">
的价格。
正如我之前提到的,我试图一次获得所有这些信息,这样我就可以在每个循环结束时将它们作为单个插入语句查询到数据库中。
当然可以使用 node.Descendants("img")
或 node.Descendants("div").Where(d => d.Attributes.Contains("itemprop") && d.Attributes["itemprop"].Value.Equals("price"))
希望对您有所帮助。
当然可以使用另一个 XPath 在给定元素内进行查询。需要注意的是,许多人一直困扰的一件事是,永远不要以 /
开始相对 XPath,因为它会搜索整个文档,如果需要,则以 ./
开始,例如 (SelectSingleNode()
假设总是在这里找到目标元素,否则需要先检查结果是否不是 null
) :
foreach (HtmlNode node in tempHtml.DocumentNode.SelectNodes("//article[@itemprop='product']"))
{
img = node.SelectSingleNode(".//img").GetAttributeValue("src","");
brand = node.SelectSingleNode(".//div[@itemprop='brand']").InnerText.Trim();
.....
}