我正在寻找可以让我使用的网络抓取框架
命中给定的端点并加载html响应
通过某些CSS选择器搜索元素
恢复该元素的xpath
有什么建议?我见过很多让我按xpath搜索的内容,但没有一个实际上为元素生成xpath。
最佳答案
似乎确实没有多少人通过CSS选择器进行搜索,而是希望将结果作为XPath,但是有一些方法可以实现。
首先,我使用JQuery和其他功能来完成此操作。这是因为JQuery的选择非常好,并且很容易找到对它的支持。您可以use JQuery in Node.js,因此您应该能够在该域中(在服务器上)而不是在客户端上实现我的代码(如我的简单示例所示)。如果这不是一个选择,则可以在下面找到使用Python的其他可能的解决方案,或者在底部找到C#入门程序。
对于JQuery方法,纯JavaScript函数对于返回XPath非常简单。在下面的示例(also on JSFiddle)中,我使用JQuery选择器检索了示例锚元素,获取了剥离的DOM元素,并将其发送给我的getXPath
函数:
<html>
<head>
<title>The jQuery Example</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
function getXPath( element )
{
var xpath = '';
for ( ; element && element.nodeType == 1; element = element.parentNode )
{
var id = $(element.parentNode).children(element.tagName).index(element) + 1;
id > 1 ? (id = '[' + id + ']') : (id = '');
xpath = '/' + element.tagName.toLowerCase() + id + xpath;
}
return xpath;
}
$(document).ready(function() {
$("#example").click(function() {
alert("Link Xpath: " + getXPath($("#example")[0]));
});
});
</script>
</head>
<body>
<p id="p1">This is an example paragraph.</p>
<p id="p2">This is an example paragraph with a <a id="example" href="#">link inside.</a></p>
</body>
</html>
如果您需要比我提供的复杂性更多的功能,则有一个完整的库可用于将更健壮的CSS选择器转换为css2xpath的XPath转换。
Python(lxml):
对于Python,您将要使用lxml的CSS选择器类(see link for full tutorial and docs)来获取xml节点。
CSSSelector类
lxml.cssselect模块中最重要的类是CSSSelector。
它提供与XPath类相同的接口,但是接受CSS
选择器表达式作为输入:
>>> from lxml.cssselect import CSSSelector
>>> sel = CSSSelector('div.content')
>>> sel #doctest: +ELLIPSIS <CSSSelector ... for 'div.content'>
>>> sel.css
'div.content'
选择器实际上会编译为XPath,您可以看到
通过检查对象来表达:
>>> sel.path
"descendant-or-self::div[@class and contains(concat(' ', normalize-space(@class), ' '), ' content ')]"
要使用选择器,只需使用文档或元素对象调用它即可:
>>> from lxml.etree import fromstring
>>> h = fromstring('''<div id="outer">
... <div id="inner" class="content body">
... text
... </div></div>''')
>>> [e.get('id') for e in sel(h)]
['inner']
使用CSSSelector等效于使用cssselect和
使用XPath类:
>>> from cssselect import GenericTranslator
>>> from lxml.etree import XPath
>>> sel = XPath(GenericTranslator().css_to_xpath('div.content'))
CSSSelector使用翻译器参数让您选择
译者使用。它可以是“ xml”(默认值),“ xhtml”,“ html”或
转换器对象。
如果要从URL加载,则可以在构建etree时直接执行:
root = etree.fromstring(xml, base_url="http://where.it/is/from.xml")
C#
有一个名为css2xpath-reloaded的库,除了CSS到XPath转换外什么也不做。
String css = "div#test .note span:first-child";
String xpath = css2xpath.Transform(css);
// 'xpath' will contain:
// //div[@id='test']//*[contains(concat(' ',normalize-space(@class),' '),' note ')]*[1]/self::span
当然,使用C#实用程序类从url获取字符串非常容易,并且无需进行任何讨论:
using(WebClient client = new WebClient()) {
string s = client.DownloadString(url);
}
至于使用CSS选择器的选择,您可以尝试Fizzler,它非常强大。这是首页示例,但您可以做更多的事情:
// Load the document using HTMLAgilityPack as normal
var html = new HtmlDocument();
html.LoadHtml(@"
<html>
<head></head>
<body>
<div>
<p class='content'>Fizzler</p>
<p>CSS Selector Engine</p></div>
</body>
</html>");
// Fizzler for HtmlAgilityPack is implemented as the
// QuerySelectorAll extension method on HtmlNode
var document = html.DocumentNode;
// yields: [<p class="content">Fizzler</p>]
document.QuerySelectorAll(".content");
// yields: [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>]
document.QuerySelectorAll("p");
// yields empty sequence
document.QuerySelectorAll("body>p");
// yields [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>]
document.QuerySelectorAll("body p");
// yields [<p class="content">Fizzler</p>]
document.QuerySelectorAll("p:first-child");
关于xpath - 具有xpath支持的Scraping框架,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31121597/