我正在尝试抓取“ li”元素,这些元素将根据要添加的“ li”元素的数量而更改其xpath。我不知道如何更好地描述它,所以我将直接进入示例以使其更加清晰。
比方说,这与抓取足球数据有关。该网站的结构如下:
<ul class="stats">
<p class="results">Man of The Match</p>
<li>Player12
<span>1 man of the match</span>
</li>
<p class="results">Goals</p>
<li>Player1
<span>2 goal(s)</span>
</li>
<p class="results">Assists</p>
<p class="results">Yellow Cards</p>
<li>Player2
<span>1 yellow card(s)</span>
</li>
<p class="results">Red Cards</p>
</ul>
如您所见,p和li元素没有相互“映射”。它们是独立的,即使p是标题,li是内容。刮擦比赛人物很容易,因为要刮擦的元素始终是“ ul / li [1] / span / text()”,而且比赛中只有一个人。但是现在出现了问题。由于目标,助攻等都不属于自己的职业,并且没有列在“ p”下,因此可能会有更多的球员得分,获得牌等。因此,在一个示例中,li [3]是一名球员,进球得分。在另一个示例中(没有目标时),li [3]可能是黄牌。
让我们看看另一个示例:
<ul class="stats">
<p class="results">Man of The Match</p>
<li>Player12
<span>1 man of the match</span>
</li>
<p class="results">Goals</p>
<li>Player1
<span>2 goal(s)</span>
</li>
<li>Player2
<span>3 goal(s)</span>
</li>
<p class="results">Assists</p>
<p class="results">Yellow Cards</p>
<li>Player2
<span>1 yellow card(s)</span>
</li>
<li>Player13
<span>3 goal(s)</span>
</li>
<p class="results">Red Cards</p>
</ul>
因此,在上面的示例中,我们将为所有锂元素使用不同的xpath。
由于网站的结构尚不清楚,我该如何编写代码以便告诉scrapy哪个“ li”元素属于目标,助攻,黄牌等。
我尝试过:
'player_stats' = extract_with_xpath('ul[@class="stats"]/p/li/text()')
这给了我所有的li元素,但没有跨度。当然,我可以在最后添加跨度,但是比起我无法将其映射到写入项(因为li总是在变化)。但实际上我想获得目标,助攻,黄牌等。
我基本上想知道如何将元素映射到相同的项目,这将根据添加的元素数量(在本例中为目标,辅助等)更改其xpath。我希望我能弄清楚我的问题,因为英语不是我的母语,所以我对可能的错误描述表示歉意。在此先感谢,非常感谢您的帮助。
答案 0 :(得分:0)
此行:response.css("ul.stats p, ul.stats li")
以与响应相同的顺序返回p
和ul
标签选择器的列表。
之后,您需要分别处理每种类型的节点。
player_data = {}
categoty = ""
for node in response.css("ul.stats p, ul.stats li"): #returs list of p and li tags selectors in the same order as in response
if '<p class="results"' in node.extract():
category = node.css("::text").extract_first()
if '<li>' in node.extract():
player = node.css("::text").extract_first().strip()
if player not in player_data.keys():
player_data[player]={}
player_data[player][category]=node.css("span::text").extract_first().strip()
print(player_data)
答案 1 :(得分:0)
您可以使用XPath的preceding-sibling
查找前面带有特定键的li
元素:
stats = response.css('.stats')
for key in stats.css('p::text').getall():
for li in stats.xpath('./li[./preceding-sibling::p[1][contains(text(), "{}")]]'.format(key)):
player = li.xpath('./text()').get()
value = li.css('span::text').get()