首页 > 解决方案 > 使用 XPath 在 Python 中选择下一个节点

问题描述

我正在尝试从维基百科国家页面中抓取人口信息。我遇到的问题是,在我试图抓取的节点中,没有关于人口的信息,而是人口只在它之前的节点中被引用。所以使用 Xpath 我试图让表达式移动到下一个节点,但找不到正确的命令。

例如以下页面:

https://en.wikipedia.org/wiki/Afghanistan

下面是一个 xpath 表达式,它让我到达我想要抓取的人口数之前的节点:

//table[@class='infobox geography vcard']//tr[@class = 'mergedtoprow']//a[contains(@href,"Demographics")]/../..

它在包含“人口统计”的表中搜索一个href,然后上升两个级别到父母的父母。但问题是标题与我要提取的数字位于不同的节点中,所以我需要一些可以转到下一个节点的东西。

我见过表达式 /following-sibling::div[1] 但它似乎对我的表达式不起作用,我不知道为什么。

如果有人能想到在上述网页中找到节点的更直接的方法,那也很好。

谢谢

编辑:下面是我正在使用的 Python 代码

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from urllib.parse import urljoin



class CountryinfoSpider(scrapy.Spider):
    name = 'CountryInfo'
    allowed_domains = ['en.wikipedia.org']
    start_urls = ['https://en.wikipedia.org/wiki/List_of_sovereign_states_in_the_2020s']

    def parse(self, response):
        ## Extract all countries names
        countries = response.xpath('//table//b//@title').extract()

        for country in countries:
            url = response.xpath('//table//a[@title="'+ country +'"]/@href').extract_first()
            capital = response.xpath('//table//a[@title="'+ country +'"]/../..//i/a/@title').extract()


            absolute_url = urljoin('https://en.wikipedia.org/', url)

            yield Request(absolute_url, callback = self.parse_country)

    def parse_country(self, response):

        test = response.xpath('//table[@class='infobox geography vcard']//tr[@class = 'mergedtoprow']//a[contains(@href,"Demographics")]/../..').extract()

        yield{'Test':test}

它比我解释的要复杂一些,但我访问了“2020 年代主权国家列表”网站。复制国家名称、大写字母和网址。然后我进入 url,将其加入维基百科并尝试使用我正在处理的 xpath 表达式来拉人口。

谢谢

标签: htmlpython-3.xparsingxpathscrapy

解决方案


我认为您问题的一般答案是:“谓词可以嵌套”。

//table[
  @class='infobox geography vcard'
]//tr[
  @class = 'mergedtoprow' and .//a[contains(@href, "Demographics")]
]/following-sibling::tr[1]/td/text()[1]

推荐阅读