【问题标题】:Normalize space in Xpath with Python scrapy使用 Python scrapy 规范化 Xpath 中的空间
【发布时间】:2021-04-04 21:40:09
【问题描述】:

我正在尝试使用 Scrapy 和 Xpath 从Stanford 网站提取内容。以下行让我得到了我想要的:

response.xpath('//h2[@class="schoolName"]/following-sibling::ul//text()').getall()

但是,列表的输出如下:

[' \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
 '\n\t\t\t\t\t\tAccounting (ACCT)\n\t\t\t\t\t', 
 '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
 '\n\t\t\t\t\t\tAction Learning Programs (ALP)\n\t\t\t\t\t', 
 '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
 '\n\t\t\t\t\t\tEconomic Analysis & Policy (MGTECON)\n\t\t\t\t\t', 
 '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', '\n\t\t\t\t\t\tFinance 
 (FINANCE)\n\t\t\t\t\t', '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
 '\n\t\t\t\t\t\tGSB General & Interdisciplinary (GSBGEN)\n\t\t\t\t\t', 
 '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', '\n\t\t\t\t\t\tHuman Resource Management 
  (HRMGT)\n\t\t\t\t\t', '\n\t\t\t']

很明显,输出中充满了 \n 和 \t 的额外空格。我不想再次遍历列表以删除这些不需要的字符,因为列表很大(为了便于阅读而被截断)。我尝试使用 Xpath 的规范化空间来解决这个问题,但它不起作用。

>>>response.xpath('normalize-space(//h2[@class="schoolName"]/following-sibling::ul//text())').getall()
['']

我做错了什么??

【问题讨论】:

标签: python xpath scrapy


【解决方案1】:

对目标节点进行更深入的索引,例如./ul/li/a/text() 而不是 ./ul//text() 修复了空项目问题。请注意,我访问了您要抓取的 webpage 并尝试了一些 xpath。

那么你所要做的就是应用 JaSON 提到的条带逻辑,例如:

map(lambda x: x.strip(), response.xpath('//h2[@class="schoolName"]/following-sibling::ul/li/a/text()'))

此外,规范化空间是否适用于许多节点取决于您的 scrapy 版本中使用的 XPath 版本。在这方面,您的帖子与Is it possible to apply normalize-space to all nodes XPath expression finds?

重复

【讨论】:

    【解决方案2】:

    你可以使用split() 代替normalize-space()

    list = [' \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
     '\n\t\t\t\t\t\tAccounting (ACCT)\n\t\t\t\t\t', 
     '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
     '\n\t\t\t\t\t\tAction Learning Programs (ALP)\n\t\t\t\t\t', 
     '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
     '\n\t\t\t\t\t\tEconomic Analysis & Policy (MGTECON)\n\t\t\t\t\t', 
     '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', '\n\t\t\t\t\t\tFinance FINANCE)\n\t\t\t\t\t', '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', 
     '\n\t\t\t\t\t\tGSB General & Interdisciplinary (GSBGEN)\n\t\t\t\t\t', 
     '\n\t\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t', '\n\t\t\t\t\t\tHuman Resource Management (HRMGT)\n\t\t\t\t\t', '\n\t\t\t']
    
    for x in list:
        print(x.split())
    

    我的输出:

    ['Accounting', '(ACCT)']
    []
    ['Action', 'Learning', 'Programs', '(ALP)']
    []
    ['Economic', 'Analysis', '&', 'Policy', '(MGTECON)']
    []
    ['Finance', 'FINANCE)']
    []
    ['GSB', 'General', '&', 'Interdisciplinary', '(GSBGEN)']
    []
    ['Human', 'Resource', 'Management', '(HRMGT)']
    []
    

    然后你可以简单地将具有内容的输出值存储在一个额外的列表中,如下所示:

    最终代码:

    ...
    
    list = response.xpath('//h2[@class="schoolName"]/following-sibling::ul//text()').getall()
    
    output = []
    
    for x in list:
      i = x.split()
      if i:
          output.append(" ".join(i))
        
    print(output)
    
    

    输出:

    ['Accounting (ACCT)', 'Action Learning Programs (ALP)', 'Economic Analysis & Policy (MGTECON)', 'Finance FINANCE)', 'GSB General & Interdisciplinary (GSBGEN)', 'Human Resource Management (HRMGT)']
    

    单线解决方案:(基于 JaSON 的想法)

    output = [data.strip() for data in response.xpath('//h2[@class="schoolName"]/following-sibling::ul//text()').getall() if data.strip()]
    
    print(output)
    
    

    输出:

    ['Accounting (ACCT)', 'Action Learning Programs (ALP)', 'Economic Analysis & Policy (MGTECON)', 'Finance FINANCE)', 'GSB General & Interdisciplinary (GSBGEN)', 'Human Resource Management (HRMGT)']
    

    【讨论】:

    • 这会根据空间拆分项目,这给了我错误的结果..Action Learning Program 应该是一个值而不是三个值
    • 我刚刚补充了 :)
    【解决方案3】:

    您需要使用strip 方法去除制表符/换行符:

    [text for text in [text.strip() for text in response.xpath('//h2[@class="schoolName"]/following-sibling::ul//text()').getall()] if text]
    

    【讨论】:

      猜你喜欢
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 2022-07-04
      • 1970-01-01
      相关资源
      最近更新 更多