之前的相关问题:
HTML XPath: Extracting text mixed in with multiple tags?
HTML XPath: Selectively avoiding tags when extracting text
//抱歉我的英语不好
我是编写网络抓取工具的初学者,我试图通过xpath从网页(中文)中提取主要内容(虽然我已经了解到有传统和机器学习方法的算法提取Web主要内容),我在编写xpath规则时非常初学。
我面对的网页包含复杂标签中的文字,我总结如下,其中字符(例如A,A2)仅指文字,' ...&#39 ;意味着更多的标签甚至嵌套没有文字。我想得到" AA2BB2CDEFGHIJKLMNOP"
...
<div id="artibody" class="art_context">
<div align="center">...</div>
<div align="center"><font>A</font>A2</div>
<div align="left"><br><br><strong>B</strong>B2</div>
<div align="left">
<p>C<a>D</a>E</p>
<p>F<a>G</a>H<a>I</a>J</p>K
</div>
<div align="center">...</div>
<div align="center"><font>L</font></div>
<p>M</p><!--M contains only text luckly-->
<p>N</p>
<p>O</p>
<p>P<span>...</span><div class="shareBox">...</div>
</p>
<span id="arctTailMark"></span>
<script>
var page_navigation = document.getElementById('page_navigation');
...
</script>
<div style="padding:10px 0 30px 0">...</div>
</div>
感谢以前的问题,我写了一条规则
&#39;串(// DIV [@class = \&#34; art_context \&#34;])&#39;
我得到的所有内容都是我想要的纯文本,但没有标签,但<script>
中的js代码也被提取出来。我尝试了以下内容,但似乎没有用。还有js代码。< / p>
&#39; string(// div [@class = \&#34; art_context \&#34;而不是(self :: script)])&#39;
以下是&#34; \ r \ n&#34;仅
&#39; // DIV [@class = \&#34; art_context \&#34;而不是(self :: script)] / text()&#39;
以下是我的问题:
1.如何编写xpath规则以满足我的需要:在div [@id =&#34; artibody&#34;]中提取内容,<script>
2.问题1的规则简单而有力吗?也许我会用div [@id =&#34; artibody&#34;]来满足更多页面,但是后代节点却完全不同。
3.对我的任务有进一步的建议吗?从一个网站提取Web内容,但主要内容位于<div>
中,具有不同的id,class和后代节点结构。我在我的笔记本电脑上运行蜘蛛(Intel corei5 3225,8G RAM),而使用机器学习算法可能会显着降低爬行速度。同时编写许多xpath规则似乎很烦人。
如果你能就这个问题(以及我的英语)给我任何建议,我会很感激。
答案 0 :(得分:1)
要获取除script
内容之外的所有后代文本节点,您可以使用:
//div[@class="art_context"]//*[not(self::script)]/text()
使用自然语言:“从不是div[@class="art_context"]
元素的所有script
元素的后代中获取所有文本节点。”
//
需要div[@class="art_context"]
来选择后代,而不仅仅是孩子。
相比之下,问题中的//div[@class="art_context" and not(self::script)]/text()
表达式显示了“div[@class="art_context"]
元素的所有script
元素的所有文本节点子。 “
因此,问题中表达式中的and not(self::script)
部分是多余的,因为所有表达式都在做,只是选择//div[@class="art_context"]
,然后/text()
部分只选择文本-node直接指向div
的子节点,这只是换行符。
此外,如果不是使用XPath来获取文本节点集,而是希望使用XPath将结果作为单个字符串获取,则可以使用函数string-join(…)
和normalize-space(…)
:
normalize-space(string-join(//div[@class="art_context"]//*[not(self::script)]/text(), ""))