【问题标题】:Extracting 'a' tags containing specific substring with Python's BeautifulSoup使用 Python 的 BeautifulSoup 提取包含特定子字符串的“a”标签
【发布时间】:2016-08-31 18:17:35
【问题描述】:

使用 BeautifulSoup,我想在它们的 href 字符串中只返回包含“Company”而不是“Sector”的“a”标签。有没有办法在 re.compile() 中使用正则表达式来只返回公司而不是部门?

代码:

soup = soup.findAll('tr')[5].findAll('a') print(soup)

输出

[<a class="example" href="../ref/index.htm">Example</a>,  
<a href="?Company=FB">Facebook</a>,  
<a href="?Company=XOM">Exxon</a>,  
<a href="?Sector=5">Technology</a>,  
<a href="?Sector=3">Oil & Gas</a>]  

使用这个方法:

import re soup.findAll('a', re.compile("Company"))

返回:

AttributeError: 'ResultSet' object has no attribute 'findAll'

但我希望它返回(没有扇区):

[<a href="?Company=FB">Facebook</a>,
<a href="?Company=XOM">Exxon</a>]

使用:

  • Urllib.request 版本:3.5
  • BeautifulSoup 版本:4.4.1
  • 熊猫版本:0.17.1
  • Python 3

【问题讨论】:

    标签: python web-scraping tags beautifulsoup recompile


    【解决方案1】:

    使用soup = soup.findAll('tr')[5].findAll('a') 然后soup.findAll('a', re.compile("Company")) 覆盖原来的汤变量。 findAll 返回一个 ResultSet,它基本上是一个 BeautifulSoup 对象的数组。尝试使用以下方法获取所有“公司”链接。

    links = soup.findAll('tr')[5].findAll('a', href=re.compile("Company"))
    

    要获取这些标签中包含的文本:

    companies = [link.text for link in links]
    

    【讨论】:

    • 感谢您的帮助!有没有简单的取值方法——比如soup.findAll('tr')[5].findAll('a', href=re.compile("Company")).value()得到["Facebook", "Exxon"]
    • 是的,有。我用这些附加信息编辑了我的帖子。您可以通过在生成器语句中替换 links 一步完成所有操作,但为了便于阅读,我不建议这样做。
    • 您是否有类似的简单方法来获取 href 值——例如,companyHref = [link.get for link in links]
    • 保持这两个值链接的一种方法是使用字典理解。与上面相同的概念,但现在结果是一个字典,其中键是公司名称,对应的值是 href 属性 companies = {link.text: link.href for link in links}。没有测试这个,顺便说一句。
    • 不,它会创建一个关联这两个值的字典。字典的格式为d={"Facebook":"?Company=FB", "Exxon": "?Company=XOM"},您可以在其中使用d["Facebook"] 访问href 或使用d.items() 遍历它们
    【解决方案2】:

    您可以使用 css 选择器 获取 href 以 ?Company 开头的所有 a 标签:

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html)
    
    a = soup.select("a[href^=?Company]")
    

    如果你想从第六个 tr 开始,你可以使用 nth-of-type

     .select("tr:nth-of-type(6) a[href^=?Company]"))
    

    【讨论】:

      【解决方案3】:

      感谢@Padriac Cunningham 和@Wyatt I 的上述回答!这是我想出的一个不太优雅的解决方案:

      import re
      for i in range(1, len(soup)):
          if re.search("Company" , str(soup[i])):
              print(soup[i])
      

      【讨论】:

        【解决方案4】:

        另一种方法是 xpath,它支持通过 XML 文档中的属性进行查询的 AND/NOT 操作。不幸的是,BeautifulSoup 本身不处理 xpath,但 lxml 可以:

        from lxml.html import fromstring
        import requests
        
        r = requests.get("YourUrl")
        tree = fromstring(r.text)
        #get elements with company in the URL but excludes ones with Sector
        a_tags = tree.xpath("//a[contains(@href,'?Company') and not(contains(@href, 'Sector'))]")
        

        【讨论】:

          最近更新 更多