【问题标题】:Handle Key-Error whilst scraping抓取时处理键错误
【发布时间】:2018-02-04 02:02:58
【问题描述】:

我目前正在编写一个脚本来从ClinicalTrials.gov 中抓取数据。为此,我编写了以下脚本:

def clinicalTrialsGov (id):
    url = "https://clinicaltrials.gov/ct2/show/" + id + "?displayxml=true"
    data = BeautifulSoup(requests.get(url).text, "lxml")
    studyType = data.study_type.text
    if studyType == 'Interventional':
        allocation = data.allocation.text
        interventionModel = data.intervention_model.text
        primaryPurpose = data.primary_purpose.text
        masking = data.masking.text
        enrollment = data.enrollment.text
    officialTitle = data.official_title.text
    condition = data.condition.text
    minAge = data.eligibility.minimum_age.text
    maxAge = data.eligibility.maximum_age.text
    gender = data.eligibility.gender.text
    healthyVolunteers = data.eligibility.healthy_volunteers.text
    armType = []
    intType = []
    for each in data.findAll('intervention'):
        intType.append(each.intervention_type.text)
    for each in data.findAll('arm_group'):
        armType.append(each.arm_group_type.text)
    citedPMID = tryExceptCT(data, '.results_reference.PMID')
    citedPMID = data.results_reference.PMID
    print(citedPMID)
    return officialTitle, studyType, allocation, interventionModel, primaryPurpose, masking, enrollment, condition, minAge, maxAge, gender, healthyVolunteers, armType, intType

但是,以下脚本并不总是有效,因为并非所有研究都会包含所有项目(即,KeyError 会出现)。为了解决这个问题,我可以简单地将每个语句包装在一个 try-except 捕获中,如下所示:

try:
  studyType = data.study_type.text
except:
  studyType = ""

但这似乎是一种不好的实现方式。什么是更好/更清洁的解决方案?

【问题讨论】:

标签: python error-handling web-scraping data-extraction


【解决方案1】:

这是个好问题。在我解决它之前,让我说您应该考虑将 BeautifulSoup (BS) 构造函数的第二个参数从 lxml 更改为 xml。否则,BS 不会将已解析的标记标记为 XML(要自己验证这一点,请访问代码中 data 变量上的 is_xml 属性)。

您可以通过将所需元素名称列表传递给find_all() 方法来避免在尝试访问不存在的元素时产生错误:

subset = ['results_reference','allocation','interventionModel','primaryPurpose','masking','enrollment','eligibility','official_title','arm_group','condition']

tag_matches = data.find_all(subset)

然后,如果您想从标签列表中获取特定元素而不遍历它,您可以使用标签名称作为键将其转换为字典:

tag_dict = dict((tag_matches[i].name, tag_matches[i]) for i in range(0, len(tag_matches)))

【讨论】:

  • 这很好用,谢谢。但是,某些记录(例如NCT02170532)将具有多种干预类型,您的代码不会显示所有这些类型。关于如何做到这一点的任何想法?
  • 是的,好吧,我不得不承认第三行中的生成器可能与遍历列表并检查每个元素上的字符串相等性一样昂贵。至于处理多种干预类型,我将把它作为练习留给你。考虑到你已经知道的,这应该很简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
  • 1970-01-01
  • 2010-11-27
  • 2019-04-23
相关资源
最近更新 更多