python - Selenium 中的相对选择器?

标签 python selenium xpath scrapy css-selectors

我想知道 Selenium 中是否有像 Scrapy 中的 ele.css 选择器那样的“相对”选择器。例如,在 Scrapy 中你可以这样做:

for li in response.css('ul.rows li p.result-info'):
    lnk = li.css('a::attr(href)').extract_first()
    prc = li.css('span.result-meta span.result-price::text').extract_first()
    sqf = li.css('span.result-meta span.housing::text').extract_first()
    loc = li.css('span.result-meta span.result-hood::text').extract_first()
    objct = {
        'lnk': lnk,
        'prc': prc,
    }
    if sqf:
        chunk = sqf.split()
        objct['sqf'] = chunk[len(chunk)-1]
    if loc:
        objct['loc'] = loc
    yield objct

在 Selenium 中可以做这样的事情吗?

现在我一直在使用以下代码,这显然会产生问题,因为路径不相关。比如说,一次抓取每件商品的所有详细信息(即商品 A 的价格、尺寸、颜色,然后是商品 B 的价格、尺寸、颜色,然后是商品 C 的价格、尺寸、颜色,所以等等),我被困住了?抓取所有商品的一项详细信息(即商品 A、商品 B 和商品 C 的价格,然后是商品 A、商品 B、商品 C 的尺寸),如以下代码所示。

discoverable_cards = browser.find_elements(By.XPATH, '//div[@class="discoverableCard"]')
product_type = browser.find_elements(By.XPATH, '//div[@class="discoverableCard-body"]/div[1]/span')
titles = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-title")]')
descriptions = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-description")]')
categories = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-category")]')
balances = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-balance")]')
currencies = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-currencyCode")]')
percentages = browser.find_elements(By.XPATH, '//div[contains(@class, "discoverableCard-percent")]')
statuses = browser.find_elements(By.XPATH, '//span[contains(@class, "discoverableCard-formattedDate")] | //div[contains(@class, "discoverableCard-InDemandBottomLabel")]')

HTML 示例(以及我的意思的示例)

<discoverable-card ng-repeat="campaign in campaigns track by campaign.clickthroughUrl" ng-click="cardClick()" gogo-test="card_1" lazy-load-image="true" discoverable="campaign" iggref="pica" class="ng-scope ng-isolate-scope"><div class="discoverableCard">
  <a in-view="$inview &amp;&amp; trackImpression()" ng-click="clickDiscoverable($event)" href="/projects/tastetro-spice-system-vegan/coming_soon/pica" gogo-test="card">
    <div class="discoverableCard-image lazyloaded" ng-class="{'lazyload': lazyLoadImage}" id="discoverableCard-image" data-bgset="https://c1.iggcdn.com/indiegogo-media-prod-cld/image/upload/c_fill,f_auto,h_273,w_273/cvuilsvvspmvmxhdynup.jpg" style="background-image: url(&quot;https://c1.iggcdn.com/indiegogo-media-prod-cld/image/upload/c_fill,f_auto,h_273,w_273/cvuilsvvspmvmxhdynup.jpg&quot;);">
    <picture style="display: none;"><source data-srcset="https://c1.iggcdn.com/indiegogo-media-prod-cld/image/upload/c_fill,f_auto,h_273,w_273/cvuilsvvspmvmxhdynup.jpg" sizes="273px" srcset="https://c1.iggcdn.com/indiegogo-media-prod-cld/image/upload/c_fill,f_auto,h_273,w_273/cvuilsvvspmvmxhdynup.jpg"><img alt="" class="lazyautosizes lazyloaded" data-sizes="auto" data-parent-fit="cover" sizes="273px"></picture></div>
    <div class="discoverableCard-body">
      <!-- ngIf: viewModel.isCampaign() --><div ng-if="viewModel.isCampaign()" class="discoverableCard-type discoverableCard-type--crowdfunding ng-scope">
           <span class="discoverableCard-type--crowdfundingLabel ng-binding" ng-bind="i18n.t('discoverable_card.type_label_campaign')">Funding</span>
           <!-- ngIf: !user && viewModel.isSaveForLaterCompatible() --><div user-auth-modal="" ng-if="!user &amp;&amp; viewModel.isSaveForLaterCompatible()" ng-click="toggleSavedForLater($event)" banner="i18n.t('discoverable_card.auth_modal_banner')" class="ng-scope ng-isolate-scope"><span class="campaignLoginModal" ng-click="openModal()" ng-transclude="">
             <span class="iggPopoverHtml ng-binding ng-scope ng-isolate-scope" ng-class="{ 'entreTooltip' : entre }" ng-bind-html="trustedHtml" igg-popover="" placement="top" aria-label="Save for later" role="img" aria-disabled="false" html="<svg><use xlink:href='#icon-icon-follow'></use></svg>"><svg><use xlink:href="#icon-icon-follow"></use></svg></span>
           </span><user-auth-modal banner="banner" status="status" class="ng-isolate-scope"></user-auth-modal></div><!-- end ngIf: !user && viewModel.isSaveForLaterCompatible() -->
           <!-- ngIf: user && viewModel.isSaveForLaterCompatible() && !viewModel.isSavedForLater() -->
           <!-- ngIf: user && viewModel.isSaveForLaterCompatible() && viewModel.isSavedForLater() -->
      </div><!-- end ngIf: viewModel.isCampaign() -->
      <!-- ngIf: viewModel.isProduct() -->
      <!-- ngIf: viewModel.isOffering() -->
      <div class="discoverableCard-title ng-binding discoverableCard-lineClamp2" ng-class="::viewModel.titleClampClass()" gogo-test="title" ng-bind="::viewModel.discoverable.title">TasteTro Spice System</div>
      <div class="discoverableCard-description ng-binding discoverableCard-lineClamp3" ng-class="viewModel.descriptionClampClass()" ng-bind="::viewModel.discoverable.tagline">An intelligent spice rack that delivers mouthwatering spice blends at the touch of a button.</div>
      <!-- ngIf: viewModel.isOffering() -->
      <div class="discoverableCard-category ng-binding" gogo-test="category" ng-click="clickCategory($event)" ng-bind="::viewModel.discoverable.category">Food &amp; Beverages</div>
      <!-- ngIf: viewModel.showCrowdFundingProgress() -->
      <!-- ngIf: viewModel.isStandardCampaign() -->
      <!-- ngIf: viewModel.isInDemandCampaign() -->
      <!-- ngIf: viewModel.isPreLaunchCampaign() --><div ng-if="viewModel.isPreLaunchCampaign()" class="discoverableCard-preLaunchBulletPoint ng-binding ng-scope" ng-bind="::viewModel.discoverable.bulletPoint">Register to get access to TasteTro's secret perks!</div><!-- end ngIf: viewModel.isPreLaunchCampaign() -->
      <!-- ngIf: viewModel.isPreLaunchCampaign() --><div ng-if="viewModel.isPreLaunchCampaign()" class="discoverableCard-LaunchingSoon ng-scope">
        <svg-icon icon="icon-rocket" class="ng-isolate-scope"><svg class="iconLaunchingRocket" aria-label="Rocket Icon" role="img" aria-disabled="false">
  <use xlink:href="#icon-rocket"></use>
</svg>
</svg-icon>
        <span class="discoverableCard-LaunchingSoonLabel ng-binding" ng-bind="::i18n.t('discoverable_card.launching_soon_label')">Launching Soon</span>
      </div><!-- end ngIf: viewModel.isPreLaunchCampaign() -->
      <!-- ngIf: viewModel.isProduct() -->
      <!-- ngIf: viewModel.isOffering() -->
    </div>
    <!-- ngIf: viewModel.isOffering() -->
  </a>
</div>
</discoverable-card>

在上面的示例中,我想做的是选择 discoverable-card (即 discoverable_card = browser.find_elements(By.XPATH, '//discoverable-card '),然后进行进一步选择,如下所示:dc_child = discoveryable_card.find_elements(By.XPATH, 'relative/path/to/child')

最佳答案

您可以简单地选择已定义元素的子/后代元素,如下所示:

discoverable_cards = browser.find_elements(By.XPATH, '//discoverable-card')
for card in discoverable_cards:
    dc_child = card.find_element(By.XPATH, './relative/path/to/child')

请注意,您应该在子 (./)/后代 (.//) 定位符的开头指定点以指向当前 元素

关于python - Selenium 中的相对选择器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51052735/

相关文章:

python - 使用python从文件中读取 float

python - 无需循环即可替换列表中的相同元素

java - Selenium 2 WebDriver 找不到链接

java - 如何在移动自动化中找到正确的appActivity?

python - svg 的 xpath,无法根据路径属性定位

python - 自定义 Python 库仅在 ArchLinux 中引发 ImportError

python - 按值排序后如何按字母顺序对字典的键进行排序?

python - 使用 selenium 和 python 捕获 AJAX 响应

java - Wiremock 和 XPath 属性测试

java - 使用 Selenium、Java 查找并单击元素