【问题标题】:Parse 'a' tags based on attribute using Python and BeautifulSoup使用 Python 和 BeautifulSoup 基于属性解析“a”标签
【发布时间】:2013-12-24 07:40:11
【问题描述】:

使用这段 html:

    <td align="left">
     <a class="playerLink" href="http://bbroto.baseball.cbssports.com/players/playerpage/2000032">
      Russell, Addison
     </a>
     SS OAK  - Won at $0
     <br>
      <a class="playerLink" href="http://bbroto.baseball.cbssports.com/players/playerpage/556425">
       Vargas, Jason
      </a>
      SP LAA
      <span title="Angels interested in bringing back Jason Vargas">
       <a class="playerLink" href="http://bbroto.baseball.cbssports.com/players/playerpage/556425" subtab="Update">
        <img border="0" height="10" src="http://sports.cbsimg.net/images/news-note-recent.gif" width="10"/>
       </a>
      </span>
      - Dropped
     </br>
    </td>

我只想显示没有 subtab = "Update" 的块。但我无法弄清楚如何使用 BeautifulSoup 在 Python 循环中引用子选项卡。这是我尝试过的:

        soup = BeautifulSoup(html)
        pl = soup.findAll('a',{'class': 'playerLink'})
        for a in pl:
            if a.subtab == "Update":
                print "UPDATE"
            else:
                print "Player Name: " + a.text

我也尝试在 findAll 部分引用子类型:

        pl = soup.findAll('a',{'class': 'playerLink'}, {'subtype':0})

这些方法都不起作用。我的问题是,在所有情况下,该类都是“playerLink”,因此该子类型是我可以区分它的唯一方法。我对 BS 很陌生,所以我不太擅长处理标签和属性。在第二个示例中,如果我只想要 subtype=Update 可能会起作用,但我想要每个不存在子类型的标签。

【问题讨论】:

  • 'subtab' not in a.attrs

标签: python html python-2.7 web-scraping beautifulsoup


【解决方案1】:

a.attrs&lt;a&gt; 的属性作为字典返回。您可以使用'subtab' not in a.attrs 来检查&lt;a&gt; 标签是否没有subtab 属性:

from bs4 import BeautifulSoup, SoupStrainer # pip install beautifulsoup4

player_links = SoupStrainer('a', 'playerLink')
soup = BeautifulSoup(html, parse_only=player_links)
names = [a.get_text().strip()
         for a in soup.find_all(player_links) if 'subtab' not in a.attrs]
print(names)
# -> ['Russell, Addison', 'Vargas, Jason']

我找不到在the documentation 中提到它的位置,但似乎指定subtab=False 也可以排除任何具有subtab 属性的标签:

from bs4 import BeautifulSoup, SoupStrainer # pip install beautifulsoup4

player_links = SoupStrainer('a', 'playerLink', subtab=False)
soup = BeautifulSoup(html, parse_only=player_links)
names = [a.get_text().strip()
         for a in soup.find_all(player_links)]
print(names)

如果找到的标签 (player_links) 没有嵌套,那么您可以省略 .find_all(player_links) 调用:

from bs4 import BeautifulSoup, SoupStrainer # pip install beautifulsoup4

player_links = SoupStrainer('a', 'playerLink', subtab=False)
soup = BeautifulSoup(html, parse_only=player_links)
names = [a.get_text().strip() for a in soup]
print(names)

【讨论】:

    【解决方案2】:

    您可以使用getattr() 函数来检查元素是否具有属性:

    from bs4 import BeautifulSoup
    import sys
    
    soup = BeautifulSoup(open(sys.argv[1], 'r'), 'html')
    
    for a in soup.find_all('a', attrs={'class': 'playerLink'}):
        #if getattr(a, 'subtab'): continue
        if a.get('subtab'): continue
        print(a.get_text("", strip=True))
    

    像这样运行它:

    python3 script.py htmlfile
    

    它产生:

    Russell, Addison
    Vargas, Jason
    

    【讨论】:

    • 这似乎不起作用。它在每种情况下都返回 false。如果我插入 print getattr(a, 'subtab') 它在每种情况下都返回“None”。可能是因为 Python 2.7 没有 getattr 函数?
    • @MichaelT:这是因为getattr() 返回一个bool。您需要比较它来决定是否打印。我没有那样编码。如果你修改了一些代码,试着知道你在做什么以及为什么。
    • 很公平。我的错。我不擅长 Python,我认为如果我使用 print 命令,布尔值会打印 true 或 false 或 0 或 1。但是当我添加这个时 -- if getattr(a, 'subtab'): -- 在每种情况下它仍然是错误的。
    • @MichaelT:是的。我在考虑您之前的评论,因为我在发布之前已经对其进行了测试。也许您忘记了continue 或类似的东西,同时尝试将其调整为您的原始源代码。简单地了解您可以使用您发现的a.attrs 或qmorgan 的解决方案来检查这样的属性。有很多方法,其中大多数都有效。
    • 现在我再看一遍,我认为您的代码不起作用。如果您删除 if 行,它的工作方式相同,因为带有 subtab 属性的 a 标签没有文本,所以您仍在打印其文本,它只是空白。因此,如果您说打印“subtab”而不是继续,它不会打印“subtab”。
    【解决方案3】:

    一个简单但不是特别优雅的解决方案就是在每个元素中搜索字符串“subtab”:

    for a in pl:
        if 'subtab' in a.prettify():
            print "UPDATE"
        else:
            print "Player Name: " + a.text
    

    【讨论】:

    • 你不需要将a标签转换成字符串来判断它是否有subtab属性。你可以改用'subtab' not in a.attrs
    • 很高兴知道 - 谢谢!您的解决方案要好得多。
    【解决方案4】:

    弄乱了 attrs 函数,我发现这是可行的:

    if str(a.attrs).find('subtab') > 0
    

    这可能不是最干净的方法,但它确实有效。

    【讨论】:

    【解决方案5】:

    你可以试试这个:

    containers = page_soup.findAll("a", {"class":"playerLink"})
    for container in containers:
          url = ("<a href='%s'>%s</a>" %(container.get("href"), container.a))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-24
      • 2012-05-22
      • 2017-11-27
      • 1970-01-01
      • 2013-03-20
      • 2019-05-19
      • 2012-01-05
      • 1970-01-01
      相关资源
      最近更新 更多