使用beautifulsoup进行Python网络抓取 - 无法从Clinicaltrials.gov中提取首席调查员

问题描述 投票:1回答:3

(免责声明:我是一个Python和网络抓取菜鸟,但我正在尽力学习)。

我正在尝试从clinicaltrials.gov的研究中提取3个关键数据点。他们有一个API,但API没有捕获我需要的东西。我希望得到(1)该研究的简短描述,(2)首席研究员(PI),以及(3)与该研究相关的一些关键词。我相信我的代码捕获1和3,但不是2.我似乎无法弄清楚为什么我没有获得首席调查员的名字。以下是我的代码中的两个网站:

https://clinicaltrials.gov/ct2/show/NCT03530579 https://clinicaltrials.gov/ct2/show/NCT03436992

这是我的代码(我知道PI代码错了,但我想证明我尝试过):

import pandas as pd
import requests
from bs4 import BeautifulSoup
import csv   

fields=['PI','Project_Summary', 'Keywords']
with open(r'test.csv', 'a') as f:
     writer = csv.writer(f)
     writer.writerow(fields)

urls = ['https://clinicaltrials.gov/ct2/show/NCT03436992','https://clinicaltrials.gov/ct2/show/NCT03530579']
for url in urls:

     response = requests.get(url)
     soup = BeautifulSoup(response.content, 'html.parser')
     #get_keywords
     for rows in soup.find_all("td"):
          k = rows.get_text()     
          Keywords = k.strip()
     #get Principal Investigator   
     PI = soup.find_all('padding:1ex 1em 0px 0px;white-space:nowrap;')

     #Get description    
     Description = soup.find(class_='ct-body3 tr-indent2').get_text()
     d = {'Summary2':[PI,Description,Keywords]} 

     df = pd.DataFrame(d)
     print (df)
     import csv   
     fields=[PI,Description, Keywords]
     with open(r'test.csv', 'a') as f:
          writer = csv.writer(f)
          writer.writerow(fields)
python web-scraping beautifulsoup html-parsing export-to-csv
3个回答
3
投票

您可以使用以下选择器

即yaazkssvpoi

PI = soup.select_one('.tr-table_cover [headers=name]').text

import requests from bs4 import BeautifulSoup urls = ['https://clinicaltrials.gov/ct2/show/NCT03530579', 'https://clinicaltrials.gov/ct2/show/NCT03436992','https://clinicaltrials.gov/show/NCT03834376'] with requests.Session() as s: for url in urls: r = s.get(url) soup = BeautifulSoup(r.text, "lxml") item = soup.select_one('.tr-table_cover [headers=name]').text if soup.select_one('.tr-table_cover [headers=name]') is not None else 'No PI' print(item) .class selector[]选择器。之间的空格是attribute,指定右侧检索的元素是左侧的子元素


2
投票

我只是用熊猫来获得桌子。这将返回一个数据帧列表。然后,您可以遍历这些以查找PI:

descendant combinator

0
投票

所以有很多方法可以走下DOM树,你的方式非常“脆弱”。这意味着您选择从中开始搜索的选择器非常具体,并且绑定到CSS样式,它可以比整个文档的结构更容易更改。

但是,如果我是你,我会根据某些标准过滤某些节点,然后在筛选噪音时专注于该特定组。

因此,查看您显示的那些网址,数据显示结构整齐,并使用表格。基于此我们可以做出一些假设

  1. 它是表格内的数据
  2. 它将包含其中的“主要调查员”字符串
tables = pd.read_html(url)
for table in tables:
    try:
        if 'Principal Investigator' in table.iloc[0,0]:
            pi =  table.iloc[0,1]
    except:
        continue

在这一点上,我们在# get all the tables in the page tables = soup.find_all('table') # now filter down to a smaller set of tables that might contain the info refined_tables = [table for table in tables if 'principal investigator' in str(table).lower()] 列表中有一个强大的候选者可能实际上包含我们的主表,并且理想情况下大小为1,假设我们使用的“主要调查员”过滤器不在其他表中的任何其他位置。

refined_tables

在这里,通过查看网站所做的是他们使用属性principal_investigator = [ele for ele in refined_tables.findAll('td') if 'name' in ele.attrs['headers']][0].text 在表格行中分配headers标记的角色。

所以从本质上讲,只需从顶层开始考虑它,并通过简单的步骤尽可能地缩小范围,以帮助您找到所需的内容。

© www.soinside.com 2019 - 2024. All rights reserved.