【问题标题】:Get contents by class names using Beautiful Soup使用 Beautiful Soup 按类名获取内容
【发布时间】:2012-07-04 14:31:24
【问题描述】:

使用 Beautiful Soup 模块,如何获取类名为 feeditemcontent cxfeeditemcontentdiv 标签的数据?是吗:

soup.class['feeditemcontent cxfeeditemcontent']

或:

soup.find_all('class')

这是 HTML 源代码:

<div class="feeditemcontent cxfeeditemcontent">
    <div class="feeditembodyandfooter">
         <div class="feeditembody">
         <span>The actual data is some where here</span>
         </div>
     </div>
 </div> 

这是 Python 代码:

 from BeautifulSoup import BeautifulSoup
 html_doc = open('home.jsp.html', 'r')

 soup = BeautifulSoup(html_doc)
 class="feeditemcontent cxfeeditemcontent"

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    Beautiful Soup 4 将“class”属性的值视为列表而不是字符串,这意味着 jadkik94 的解决方案可以简化:

    from bs4 import BeautifulSoup                                                   
    
    def match_class(target):                                                        
        def do_match(tag):                                                          
            classes = tag.get('class', [])                                          
            return all(c in classes for c in target)                                
        return do_match                                                             
    
    soup = BeautifulSoup(html)                                                      
    print soup.find_all(match_class(["feeditemcontent", "cxfeeditemcontent"]))
    

    【讨论】:

      【解决方案2】:

      试试这个,也许这个简单的东西太多了,但它有效:

      def match_class(target):
          target = target.split()
          def do_match(tag):
              try:
                  classes = dict(tag.attrs)["class"]
              except KeyError:
                  classes = ""
              classes = classes.split()
              return all(c in classes for c in target)
          return do_match
      
      html = """<div class="feeditemcontent cxfeeditemcontent">
      <div class="feeditembodyandfooter">
      <div class="feeditembody">
      <span>The actual data is some where here</span>
      </div>
      </div>
      </div>"""
      
      from BeautifulSoup import BeautifulSoup
      
      soup = BeautifulSoup(html)
      
      matches = soup.findAll(match_class("feeditemcontent cxfeeditemcontent"))
      for m in matches:
          print m
          print "-"*10
      
      matches = soup.findAll(match_class("feeditembody"))
      for m in matches:
          print m
          print "-"*10
      

      【讨论】:

      • classes = dict(tag.attrs).get('class', '')try except 块要短得多,而且它的功能是一样的。
      • @DoronCohen 是否需要dict()?似乎没有工作。
      • @Mark 我得到一个没有dict() 的例外,因为它是一个列表TypeError: list indices must be integers, not str。此外,此答案假设 Beautiful Soup 3(可能是您看到不同结果的原因),您可能应该使用版本 4 并使用其他答案。
      • 哦,是的,我正在使用 4,可能就是这样。谢谢!
      【解决方案3】:

      soup.findAll("div", class_="feeditemcontent cxfeeditemcontent")

      所以,如果我想从 stackoverflow.com 获取类头 &lt;div class="header"&gt; 的所有 div 标签,BeautifulSoup 的示例将类似于:

      from bs4 import BeautifulSoup as bs
      import requests 
      
      url = "http://stackoverflow.com/"
      html = requests.get(url).text
      soup = bs(html)
      
      tags = soup.findAll("div", class_="header")
      

      已经在 bs4 documentation.

      【讨论】:

        【解决方案4】:
        from BeautifulSoup import BeautifulSoup 
        f = open('a.htm')
        soup = BeautifulSoup(f) 
        list = soup.findAll('div', attrs={'id':'abc def'})
        print list
        

        【讨论】:

          【解决方案5】:
          soup.find("div", {"class" : "feeditemcontent cxfeeditemcontent"})
          

          【讨论】:

          • 或soup.findAll,如果你想要多个(使用相同的参数)
          • 出于显而易见的原因,我不会真正使用该代码。检查我的答案。有一个相关的错误报告。
          • 你能解释一下为什么你不赞成我的解决方案吗?它完美无缺。
          • 重点是您的代码仅适用于这个 very 特定的 HTML 字符串。代码何时失败的最简单示例是class=cxfeeditemcontent feeditemcontent。一般观点是:class="a b c" 应被视为包含 a、b、c 的 set,而不是有序的 list
          【解决方案6】:

          查看此错误报告:https://bugs.launchpad.net/beautifulsoup/+bug/410304

          如你所见,美汤并不能真正将class="a b"理解为两个类ab

          但是,正如第一条评论中出现的那样,一个简单的正则表达式就足够了。在你的情况下:

          soup = BeautifulSoup(html_doc)
          for x in soup.findAll("div",{"class":re.compile(r"\bfeeditemcontent\b")}):
              print "result: ",x
          

          注意:这已在最近的测试版中得到修复。我没有浏览最新版本的文档,也许你可以这样做。或者,如果你想使用旧版本让它工作,你可以使用上面的。

          【讨论】:

            猜你喜欢
            • 2021-02-22
            • 1970-01-01
            • 2018-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-07
            • 1970-01-01
            • 2017-02-19
            相关资源
            最近更新 更多