我正在尝试阅读具有相同价值的网站(www.joindota.com)的特定部分。我将用网站上的例子解释我想做什么:
以下HTML是我想从网站上阅读的内容的一部分:
<div id="matchticker_coverage_content_1761" style="display:none;">
<a href="http://www.joindota.com/en/matches/16102-team-dignitas-dota-vs-sk-gaming-dota" class="item">
<div class="sub" style="width: 18px; text-align: left;"><img src="http://www.gs-media.de/img/themes/joindota/ticker_9.png" border="0" alt="" /></div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/ro.gif" border="0" alt="ro" title="Romania" /> Digni</div>
<div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/dk.gif" border="0" alt="dk" title="Denmark" /> SK</div>
<div class="sub" style="float: right; text-align: right;">
<span title="Sun, 29.01.2012, 16:00 CET">tomorrow</span>
</div>
<div class="cl"></div>
</a>
<a href="http://www.joindota.com/en/matches/16101-world-elite-vs-mineski" class="item">
<div class="sub" style="width: 18px; text-align: left;"><img src="http://www.gs-media.de/img/themes/joindota/ticker_9.png" border="0" alt="" /></div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/cn.gif" border="0" alt="cn" title="China" /> WE</div>
<div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/ph.gif" border="0" alt="ph" title="Philippines" /> Mski</div>
<div class="sub" style="float: right; text-align: right;">
<span title="Sun, 29.01.2012, 14:00 CET">tomorrow</span>
</div>
<div class="cl"></div>
</a>
....
</div>
我想阅读<div id="matchticker_coverage_content_1761" >
我只需要阅读我在那里提供的<div>
标签内的所有值。例如,它会输出:
该HTML中的所有div值都是相同的,我只需要知道如何在页面中专门“选择”<div id="matchticker_coverage_content_1761" >
,并读取该div中的所有其他div,它们就是:
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/ro.gif" border="0" alt="ro" title="Romania" /> Digni</div>
div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/dk.gif" border="0" alt="dk" title="Denmark" /> SK</div>
所有<div>
值都是相同的,我感兴趣的是其中的文本,例如Digni和vs.与SK,例如。
我只需要阅读<div id="matchticker_coverage_content_1761" > </div>
原因是因为该网站有很多这些,但我只需要阅读一个特定的部分。这是同一页面上相同的另一部分,只有所有其他div所在的div不同。
示例:
<div id="matchticker_coverage_content_1596" style="display:none;">
<a href="http://www.joindota.com/en/matches/16564-westernwolves-vs-panzer" class="item">
<div class="sub" style="width: 18px; text-align: left;"><img src="http://www.gs-media.de/img/themes/joindota/ticker_9.png" border="0" alt="" /></div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/fr.gif" border="0" alt="fr" title="France" /> Wolves</div>
<div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/de.gif" border="0" alt="de" title="Germany" /> PANZER</div>
<div class="sub" style="float: right; text-align: right;">
<span title="Tue, 31.01.2012, 21:00 CET">31.01.</span>
</div>
<div class="cl"></div>
</a>
<a href="http://www.joindota.com/en/matches/16626-panzer-vs-just-4-the-tournament" class="item">
<div class="sub" style="width: 18px; text-align: left;"><img src="http://www.gs-media.de/img/themes/joindota/ticker_9.png" border="0" alt="" /></div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/de.gif" border="0" alt="de" title="Germany" /> PANZER</div>
<div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;"><img src="http://www.gs-media.de/img/flags/de.gif" border="0" alt="de" title="Germany" /> J4T</div>
<div class="sub" style="float: right; text-align: right;">
<span title="Sun, 29.01.2012, 19:00 CET">tomorrow</span>
</div>
<div class="cl"></div>
</a>
....
</div>
请注意所有<div>
在开头<div>
内的完全相同? <div>
所有<div>
所在的<div id="matchticker_coverage_content_1596" style="display:none;">
<div id="matchticker_coverage_content_1761" style="display:none;">
与<div>
我的最终问题是,如何选择包含另一个<div>
的开头{{1}},并阅读我之前提到的具体内容?
答案 0 :(得分:6)
您经常需要专门针对每个网站定制您的抓取工具,以便为了获取数据而获取相同来自每个站点的数据点,但每个站点以不同的方式表示。
考虑到这一点,通常会发现一种模式,可以让您在某个站点内一致地识别数据点。
我冒昧chopping down your HTML samples, as well as formatting it来展示标签的层次结构;这不会影响页面的解析或显示方式,因为它是关于 in 标签的内容,而不是它们之外的内容。
通过重新排列,模式应该出现。
让我们首先识别容器<div>
元素。唯一标识这些<div>
元素的内容是id
属性,它们都具有以下形式:
<div id="matchticker_coverage_content_**some number**" style="display:none;">
(注意:您可以查找具有<div>
属性的任何style="display:none;"
元素,但非常脆弱,并且不是唯一标识容器,该属性可以任何地方其他地方应用 no 语义含义)
不幸的是,id
属性是一个问题,因为它似乎是一个数字,它是某种类型的id,并且在整个页面中不一致。如果你知道容器的id,你可以在Html Agility Pack中使用以下表达式:
\\div[id='matchticker_coverage_content_1596']
但我想你不知道它。
您真正想要的是能够查找<div>
属性以id
开始的所有matchticker_coverage_content_
个元素。
Html Agility Pack不支持这种选择器语法。但是,jQuery does具有以下语法:
div[id^='matchticker_coverage_content_']
更好的是fizzler project support this selector。所以在这种情况下,我会使用fizzler来获取那个容器。
一旦你拥有容器,就需要查看它的子元素。同样,在编辑之后,显而易见的是,您正在寻找的每个匹配(具有相关的<div>
元素)都包含在内部锚(即<a>
)元素中。因此,一旦拥有容器<div>
,您只需使用以下语法选择出锚元素的所有子元素:
/a
(如果使用fizzler,则只是容器节点上a
的选择器)
一旦你拥有了它,你真的不需要检测vs.,你可以假设它在那里,你真的想要检测球员。
这些更难,因为标签,类或ID没有任何语义。但是,有一个鉴别器。看一下播放器标签(我把它们中的一部分切掉了以便更清楚):
<div class="sub">
<img src="http://www.gs-media.de/img/themes/joindota/ticker_9.png"
border="0" alt="" /></div>
<div class="sub">
<img src="http://www.gs-media.de/img/flags/ro.gif"
border="0" alt="ro" title="Romania" /> Digni</div>
<div class="sub" style="width: 20px;">vs.</div>
<div class="sub" style="width: 103px;">
<img src="http://www.gs-media.de/img/flags/dk.gif"
border="0" alt="dk" title="Denmark" /> SK</div>
您可以看到玩家所在的<div>
标签中有<img>
个标记,其中alt
属性不为空(这很重要,因为您不希望处理第一个 <div>
元素。
识别出这些<img>
标记后,您只需获取父节点(<div>
)并从节点中获取文本即可获取播放器。第一个是第一个玩家方,第二个是第二个玩家方。
另一种方法是识别包含“vs.”的<div>
元素在其中的文字,然后看看兄弟姐妹,前一个是第一个玩家,而后一个是第二个玩家。
注意,最后一步是非常脆弱,并且总是是脆弱的,因为标签中没有语义指示符。您基本上依赖于实现细节(因为您别无选择)。
我强烈建议你在某些页面上有测试用例来解析内容并验证数据;这样,如果页面结构发生变化,您将立即知道,并可以相应地更改您的抓取逻辑。