簡體   English   中英

ClinicalTrials.gov 上表格第一行的 CSS 選擇器

[英]CSS selector for the first row of table on ClinicalTrials.gov

我在使用 web 從 ClinicalTrials.gov 抓取表格時遇到問題。

我正在嘗試在“搜索的術語和同義詞”表下提取第一行第一列中標記為“乳腺癌”的單詞的 CSS 選擇器。 這是該表的鏈接: https://clinicaltrials.gov/ct2/results/details?cond=breast+cancer

請參閱下面的屏幕截圖以了解我想要的條款:

在此處輸入圖像描述

CSS 選擇器.w3-padding-8:nth-child(1)為我提供了第一列中的所有術語。 如果搜索詞是單個詞,例如“pembrolizumab”,則此方法有效,但如果搜索詞是兩個詞,例如“乳腺癌”,則表包含多行(“塊”)並且上述 CSS 選擇器返回所有詞從這些行。

編輯:這是@neilfws 建議的代碼:

search_term_processed <- unlist(stringr::str_replace("breast cancer", " ", "+"))
ctgov_url <- paste0("https://clinicaltrials.gov/ct2/results/details?term=", search_term_processed)
ct_page <- xml2::read_html(ctgov_url)

# extract related terms
ct_page %>%
  # find elements that match a css selector
  rvest::html_elements(".w3-padding-8:nth-child(1)") %>%
  # retrieve text from element (html_text() is much faster than html_text2())
  rvest::html_text()

有誰知道 CSS 選擇器僅提取第一列和第一行(“塊”)中的術語?

class w3-padding-8td單元格包括您想要的列中列出的同義詞以及搜索和數據庫的(不需要的)研究數量。

因為每個同義詞條目后面都有兩個包含研究編號的單元格,所以以下策略可能有助於僅隔離同義詞列。

首先制作一個 html 集合 class w3-padding-8的所有td元素:

const cells = document.querySelectorAll('td.w3-padding-8');

然后,記錄第一個、第三個、第六個等單元格的innerText (因此跳過那些包含研究編號的單元格):

for (let i=0; i<cells.length; i+=3) {
  console.log(cells[i].innerText);
}

注意循環增量器使用i+=3 - 只允許包含要列出的同義詞的單元格 0,3,6... 等。

我在瀏覽器控制台上運行了這個,加載了你提供的鏈接,它返回了同義詞列表。 您可能需要修改的唯一部分是加載的表包含三個部分:“breast cancer”、“cancer”和“breast”,並且列表包含所有三個部分的同義詞。 您應該能夠隔離“乳腺癌”塊並應用相同的想法來檢索其同義詞列。

關鍵似乎是在使用i+=3的每個同義詞之后跳過兩個單元格。

它是否解決了您的問題,而不是獲取表格?

library(tidyverse)
library(rvest)

"https://clinicaltrials.gov/ct2/results/details?cond=breast+cancer" %>% 
  read_html() %>% 
  html_table() %>% 
  .[[1]] 

# A tibble: 30 × 3
   Terms                   `Search Results*` `Entire Database**`
   <chr>                   <chr>             <chr>              
 1 Synonyms                Synonyms          Synonyms           
 2 breast cancer           12,002 studies    12,002 studies     
 3 Breast Neoplasms        9,539 studies     9,539 studies      
 4 breast carcinomas       917 studies       917 studies        
 5 Breast tumor            159 studies       159 studies        
 6 cancer of the breast    66 studies        66 studies         
 7 Neoplasm of breast      61 studies        61 studies         
 8 cancer of breast        40 studies        40 studies         
 9 Carcinoma of the Breast 33 studies        33 studies         
10 CARCINOMA OF BREAST     32 studies        32 studies         
# … with 20 more rows
# ℹ Use `print(n = ...)` to see more rows

問題:

我不相信 rvest 目前不可能做到這一點,因為它依賴於選擇器級別 3,在引擎蓋下,它只允許一個帶有否定的簡單選擇器,即在:not() 內部。 這些行都處於相同的 DOM 級別,您想要的是能夠從“第一”批次中過濾掉后面的行。

對於4 級選擇器,允許在:not() 中使用選擇器列表的方法是:

tr[style]:nth-child(1) ~ tr:not( tr[style]:nth-child(n+2) ~ tr):not([style]) td:first-child

以上只是選擇器級別 4 的一個工作示例。還有其他更好的變體。

我認為這是幕后選擇器的實現細節(通過xml2?)。 比較以下內容:

在此處輸入圖像描述

parse_simple_selector,它是一個選擇器 function,反對偽 class 否定中存在非簡單選擇器。

library(rvest)

link <- 'https://clinicaltrials.gov/ct2/results/details?cond=breast+cancer'
page <- read_html(link) 
selector_list <- 'tr[style]:nth-child(1) ~ tr:not(tr[style]:nth-child(n+2) ~ tr):not([style]) td:first-child'

page |>  html_elements(selector_list) |>  html_text2() # fail
page |> html_element('tr:not(td ~ td)') # fail 
page |> html_element('tr:not(td)') # pass

現在,看一下湯篩,這是 Beautiful Soup 4 使用的 python package ,它:

提供從 CSS 1 級規范到最新的 CSS 4 級草案及更高版本的選擇器(盡管有些尚未實施)。

截至 28/7/22

選擇器級別 4 的實現細節允許在:not() 中使用選擇器列表

在此處輸入圖像描述

import requests
from bs4 import BeautifulSoup as bs

selector = 'tr[style]:nth-child(1) ~ tr:not( tr[style]:nth-child(n+2) ~ tr):not([style]) td:first-child'
soup = bs(requests.get('https://clinicaltrials.gov/ct2/results/details?cond=breast+cancer').text, 'html.parser')
soup.select(selector)

解決方案:

一些可能的選項可能包括:

  1. 實現您自己的擴展選擇器的助手
  2. 利用一個循環,該循環在使用樣式屬性找到下一個 tr 時停止,然后用目標文本找到第一個
  3. 首選解決方案,IMO,切換到 xpath 例如

page |> html_elements(xpath = '(//tr[count(preceding-sibling::tr[@style])=1 and count(following-sibling::tr[@style])>=2])//td[1]') |>  html_text(trim = T)

現在,這些是位置匹配,因此您可能決定通過使用一些涉及您的搜索詞的基於文本的匹配來改進。


在 xpath 中使用計數的想法是我從@Daniel Haley那里得到的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM