【问题标题】:Scraping html in python when you have more than one class with the same name当您有多个具有相同名称的类时,在 python 中抓取 html
【发布时间】:2015-12-10 16:04:27
【问题描述】:

也许我的术语在这里有点偏离,但希望你能明白。 我正在尝试从具有三个评级的食品评论网站上抓取数据:快乐、中立、不快乐。网站中每个计数的数量写成:

<div class="col  PL20">
  <div class="sprite-sr2-face-smile1"></div>
  <div class="sr2_score_l">25</div>
</div>
<div class="col MR20 MT20 ML20">
  <div class="sprite-sr2-face-ok2 MT20"></div>
  <div class="sr2_score_m">17</div>
</div>
<div class="col ML10 MT20">
  <div class="sprite-sr2-face-cry2 MT20"></div>
  <div class="sr2_score_m">2</div>
</div>

所以在这种情况下,快乐计数的数量是 25,中性是 17,不快乐是 2。问题是我下面的 python 代码我无法区分中性计数和不快乐计数,因为共享同一个类,是有办法解决吗?

# using BeautifulSoup4 and lxml
import urllib2 
from bs4 import BeautifulSoup  
soup = BeautifulSoup(urllib2.urlopen('http://www.openrice.com/_
en/hongkong/restaurant/central-open-kitchen/136799').read())

happy = soup.find('div', attrs={'class': 'sr2_score_l'})
print "happy rating, " + happy.string

neutral = soup.find('div', attrs={'class': 'sr2_score_m'})
print "neutral rating, " + neutral.string

unhappy = soup.find('div', attrs={'class': 'sr2_score_m'})
print "neutral rating, " + neutral.string

【问题讨论】:

    标签: python html web-scraping beautifulsoup lxml


    【解决方案1】:

    我看到了两种可能的解决方案:

    • 如果可以,添加另一个 html 类。

    • 在您找到“sr2_score_m”的行之前的行中搜索“sprite-sr2-face-cry2”类。

    为此,您可以使用 .splitlines() 从 html 文件中创建一个字符串列表,然后对其进行迭代并搜索这两个类。

    【讨论】:

      【解决方案2】:

      face-smileface-okface-cry 部分类名是您的指标:

      happy = soup.find("div", class_=re.compile(r"face-smile")).find_next_sibling("div").text
      ok = soup.find("div", class_=re.compile(r"face-ok")).find_next_sibling("div").text
      unhappy = soup.find("div", class_=re.compile(r"face-cry")).find_next_sibling("div").text
      

      示例代码(具有很好的可重用功能):

      import re
      
      from bs4 import BeautifulSoup
      
      
      def print_reviews_count(soup):
          indicators = {
              "happy": "face-smile",
              "ok": "face-ok",
              "unhappy": "face-cry",
          }
      
          for key, class_name in indicators.iteritems():
              count = soup.find("div", class_=re.compile(class_name)).find_next_sibling("div").text
              print(key, count)
      
      
      source_code = """
      <div class="col  PL20">
        <div class="sprite-sr2-face-smile1"></div>
        <div class="sr2_score_l">25</div>
      </div>
      <div class="col MR20 MT20 ML20">
        <div class="sprite-sr2-face-ok2 MT20"></div>
        <div class="sr2_score_m">17</div>
      </div>
      <div class="col ML10 MT20">
        <div class="sprite-sr2-face-cry2 MT20"></div>
        <div class="sr2_score_m">2</div>
      </div>
      """
      
      soup = BeautifulSoup(source_code, "lxml")
      print_reviews_count(soup)
      

      打印:

      ('ok', u'17')
      ('unhappy', u'2')
      ('happy', u'25')
      

      【讨论】:

      • 谢谢。第一个代码块的工作方式类似,但是当我尝试在不同的窗格中执行第二个块时,它一直说变量指示器没有定义
      • @pakkunrob 您将示例代码集成到代码中的方式可能有问题。如果不查看您当前的代码,很难说。无论如何,我认为我们可以解决这个特定的主题,请参阅stackoverflow.com/help/someone-answers
      【解决方案3】:

      实际上,在你们的帮助下,我设法编写了一个相当不错的函数,应该允许我将该函数重用于网站 url 列表

      import re
      import urllib2 
      from bs4 import BeautifulSoup
      
      website_list = [urlA, urlB....,urlX]
      
      def ratings(website):
          soup = BeautifulSoup(urllib2.urlopen(website).read())
          happy = soup.find("div", class_=re.compile(r"face-smile")).find_next_sibling("div").string
          ok = soup.find("div", class_=re.compile(r"face-ok")).find_next_sibling("div").string
          unhappy = soup.find("div", class_=re.compile(r"face-cry")).find_next_sibling("div").string
          print "happy rating, " + happy.string
          print "ok rating, " + ok.string
          print "unhappy rating, " + unhappy.string
      
      for website in website_list:
          ratings(website)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多