在同一类下使用更改的xpath刮除元素

2024-10-06 12:27:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试刮除“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”下,所以可能会有更多的球员得分、收到卡片等,因此在一个例子中,李[3]是一个进球的球员。在另一个例子中(当没有进球时),李[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>

因此在上面的示例中,我们将为所有li元素使用不同的xpath。你知道吗

我该如何编写代码来告诉scrapy哪个“li”元素属于进球、助攻、黄牌等,因为网站的结构并不十分清楚?你知道吗

我试过:

'player_stats' = extract_with_xpath('ul[@class="stats"]/p/li/text()')

这给了我所有的li元素,但没有跨度。当然,我可以在最后添加span,但是我无法将它映射到write项(因为li的总是在变化)。但事实上我想要的是进球,助攻,黄牌等等

基本上,我想知道如何将元素映射到相同的项,这将根据添加的元素数量(在本例中是goals、assists等)更改它们的xpath。我希望我能把我的问题说清楚,因为英语不是我的第一语言,我为可能的错误描述道歉。提前谢谢,非常感谢您的帮助。你知道吗


Tags: of元素statsliulxpathresultsclass
2条回答

这行:response.css("ul.stats p, ul.stats li")
返回pul标记选择器的列表,其顺序与响应中的顺序相同。 之后,需要分别处理每种类型的节点。你知道吗

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)

可以使用XPathpreceding-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()

相关问题 更多 >