用美丽的汤解读未知的网站组织

时间:2013-06-10 01:23:16

标签: python beautifulsoup web-crawler

所以我想尝试任何网站餐厅菜单,抓住它然后根据我已经拥有的算法,用它做一些事情。这是我的问题:

这些菜单总是采用不同的格式!

示例:一个菜单可能有不同的类,如价格和名称和描述,而另一个菜单可用于名称和

的价格和描述。其他一些菜单甚至在页面顶部还有额外的信息。

我的观点是每个菜单的组织和信息的显示方式因网站而异。

如果我有菜单的网站,很容易获取代码,但解析它并以相同的方式为每个餐厅组织信息是我无法弄清楚的。

所以这个问题不仅仅是这个例子...如果你有一个函数需要一个url并抓住代码并需要以某种方式组织它,那么编写代码的可能方法是什么?能够以多种不同的格式工作吗?

注意:是的,代码可能不同,但不会有很大差异。将始终存在价格,名称和描述,并且它们最有可能被分类。所以我知道在这种情况下这是可能的,我只是不知道如何开始......任何想法?

我在代码中尝试做的事情:

我想基本上创建一个字典:

{food_kind1:['name1/description1/price1','name2/description2,price2'],
 food_kind2:['name1/description1/price1','name2/description2,price2']}

food_kindX将成为菜单上各种食物的大标题,如肉类,鱼类等。

做我想要的并不难,无论格式如何,它都能够始终阅读文档。请帮忙!如果我不清楚,请告诉我

菜单示例

1:

<h2>Burgers</h2>
<div>
<header>
<h3>California</h3>
</header>
<p>sharp cheddar | hass avocado | watercress | tomatoes | raw red onions<br />
salsa verde <small><span style="font-size: 13px; line-height: 19px;">11.95$</span></small></p>
</div>

2:

<h4>ANTIPASTI</h4>
<ul>
    <span class="menuitem">Calamari Fritti</span>
    <span class="menuprice"> - $11.95</span>
    <span class="menudescription">Delicate tender calamari rings pan-fried until golden crisp. Topped with hot cherry peppers and served with our house made cocktail sauce and lemon garnish. </span>
    <br /><br />
    <span class="menuitem">Vongole Casino</span>
    <span class="menuprice"> - $10.95</span><br/>
    <span class="menudescription">Shucked littleneck clams topped with roasted red pepper, bacon and bread crumbs, then baked. </span>
</ul>

第一个有:

  • 它是<h2>标记
  • 中的food_kindX
  • 每个条目都在<div>标记
  • 该名称位于<header>标记
  • <p>代码中价格的描述,其中的价格为a <small>标记

第二个有:

  • 它是<h4>标记
  • 中的food_kindX
  • 每个条目由两个</br>标记
  • 分隔
  • 该名称位于menuitem
  • 描述在menudescription
  • 价格在menuprice

正如您所看到的,它们有点类似,因为它们具有相同的信息并以类似的方式组织,但第一个主要使用不同的标签,而第二个主要使用类。菜单真的各不相同,我需要能够始终确定类别,每餐都有它的名称,描述和价格。

1 个答案:

答案 0 :(得分:1)

考虑使用正则表达式来解释两种类型的菜单。

以下是如何刮取第一个菜单示例:

import re
from collections import defaultdict

menu_dict = defaultdict(list)

pattern = '<h2>(.*?)</h2>.*?<div>.*?<h3>(.*?)</h3>.*?<p>(.*?)<small><span .*?>(.*?)</span>'
text    = '''<h2>Burgers</h2>
                 <div>
                 <header>
                     <h3>California</h3>
                 </header>
             <p>sharp cheddar | hass avocado | watercress | tomatoes | raw red onions<br />
             salsa verde <small><span style="font-size: 13px; line-height: 19px;">11.95$</span></small></p></div>'''

results = re.findall(pattern, text, re.DOTALL)

for r in results:
    kind = r[0]
    name = r[1]
    description = r[2].replace('<br />\n', ' | ')
    price = r[3]

    value = name + '/' + description + '/' + price
    menu_dict[kind].append(value)

以下是第二个菜单的类似示例:

import re

pattern = '<span class="menuitem">(.*?)</span>.*?<span class="menuprice">(.*?)</span>.*?<span class="menudescription">(.*?)</span>'

text    = '''<h4>ANTIPASTI</h4>
                 <ul>
                     <span class="menuitem">Calamari Fritti</span>
                     <span class="menuprice"> - $11.95</span>
                     <span class="menudescription">Delicate tender calamari rings pan-fried until golden crisp. Topped with hot cherry peppers and served with our house made cocktail sauce and lemon garnish. </span>
                     <br /><br />
                     <span class="menuitem">Vongole Casino</span>
                     <span class="menuprice"> - $10.95</span><br/>
                     <span class="menudescription">Shucked littleneck clams topped with roasted red pepper, bacon and bread crumbs, then baked. </span>
                 </ul>'''

results = re.findall(pattern, text, re.DOTALL)

for r in results:
    name = r[0]
    price = r[1][3:]
    description = r[2]

希望这能回答你的问题!