【问题标题】:BeautifulSoup ignore nested tables inside tableBeautifulSoup 忽略表内的嵌套表
【发布时间】:2015-03-19 10:34:03
【问题描述】:

使用 BeautifulSoup for Python 来解析网页(不幸的是,这主要是在表格中编写的)。

这是我正在尝试使用的内容的摘录

<tr>
  <td colspan="4">
    <div class="shortmenucats">
        <span style="color: ">
            -- Fresh Baked Pastries --

        </span>
    </div>
  </td>
</tr>
<tr>  
  <td width="80%" valign="top">
    <table width="100%" cellspacing="0" cellpadding="0" border="0">
        <tbody>
            <tr>
                <td>
                    <div class="shortmenurecipes">
                        <span style="color: #000000"> Chocolate Doughnut Holes </span>
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
  </td>
  <td width="5%" valign="top"></td>
  <td width="10%" valign="top" align="right" colspan="1">
    <div class="shortmenuprices">
        <span style="color: #000000"></span>
    </div>
  </td>
  <td width="5%" valign="top" colspan="1">
  </td>
</tr>

这些是表中的两行,其中包含 10 行,它们交替出现(td 中的 div、td 中的表、td 中的 div、td 中的表等)。

我正在使用 BeautifulSoup 在父表上调用 find_all 并且由于嵌套表中的嵌套标签,它会返回每隔一行的重复项。

我首先做了一个table.find_all('td', recursive=False),但这根本没有返回任何s。 如果我在父表上调用findChildren(),我会得到一个包含一个结果的列表,但它包含结果中的所有子项。

我做错了吗?我不知道如何解决这个问题。

如果您想要我从中解析的实际网站,请点击此处: http://138.23.12.141/foodpro/shortmenu.asp?sName=University+of+California%2C+Riverside+Dining+Services&locationNum=02&locationName=Lothian+Residential+Restaurant&naFlag=1

它的代码非常混乱。我只是想解析它。

任何帮助将不胜感激。即使这只是删除重复项的一种方法。

谢谢。

【问题讨论】:

  • 那么您到底想提取哪些部分? spans 中的文字?或者,还有什么?

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


【解决方案1】:

这里的另一个选择是依赖菜单的类名和里面的类别,并且仅在向下到元素的直接父级时使用recursive=False

完整的工作代码提取菜单:

from urllib2 import urlopen
from bs4 import BeautifulSoup

url = "http://138.23.12.141/foodpro/shortmenu.asp?sName=University+of+California%2C+Riverside+Dining+Services&locationNum=02&locationName=Lothian+Residential+Restaurant&naFlag=1"
soup = BeautifulSoup(urlopen(url))

container = soup.find('div', class_='shortmenutitle').find_next_sibling('table').tr
for td in container.find_all('td', recursive=False):
    title = td.find('div', class_='shortmenumeals')

    print title.text.strip()
    for item in td.table.find_all('tr', recursive=False)[1].table.find_all('tr', recursive=False):
        print item.text.strip()
    print "-----"
    print

打印完整的菜单(不重复):

Breakfast
-- Fresh Baked Pastries --
Chocolate Doughnut Holes
Double Chocolate Mini Muffin
Fresh Baked Blueberry Bagel
Fresh Baked Plain Bagel
-- Breakfast Parfait Bar --
(V,GF) Breakfast Parfait Bar
-- Hot Cereal & Toppings --
(V) Cream of Wheat
-- Breakfast Offerings --
(V) Belgium Waffle Bar with Condiments
(V) Eggs Rancheros
(V) Vanilla Scented French Toast
(V)Hash Browns
(V.GF) Scrambled Eggs
Corned Beef Hash
Turkey Sausage Patty
-- Omelet Bar --
(V,GF) Omelet Bar (Egg Whites Available Upon Request)
-----

Lunch
-- Soup & Deli Bar --
(V) Broccoli Cheese
Artisian Bread Bar
Chicken Tortilla
N Y Style Deli Bar
-- Global Sizzle --
(V) Jasmine Rice
(V) Steamed Sugar Snap Peas
(V) Thai Vegetable Spring Roll
Red Thai Curry Chicken (contains peanuts)
Sweet Thai Chili & Plum Dipping Sauces
Thai Curry Shrimp w/ Green Pepper
-- Urban Kitchen --
(V) Peruvian Beans
Peruvian Rotissere Chicken
-- The Grill --
(GF) Marinated Grilled Chicken Breast
(V) Skinny Fries
Turkey Club Melt
-- Healthy Vegetarian Bar --
(V) Southwestern Corn Salad
Southwest Soy Beef Wrap
-- Desserts --
Bakery Parfait Bar
Chocolate 1/2 Sheet Cake
Chocolate Mousse
Sugar Free Strawberry Orange Jell-O Gems
-- Continous Service 2pm-4:30pm --
(V) Vietnamese Tofu Spring Roll w/Sauces
Rotini w/Chicken Tomato Cream Spinach
Rotini w/Tomato Cream Spinach
Vietnamese Spring Roll with Tofu
-----

Dinner
-- Soup & Deli Bar --
(V) Broccoli Cheese
Artisian Bread Bar
Chicken Tortilla
N Y Style Deli Bar
-- Spinellis Pizza --
(V)French Bread Three Cheese Pizza
French Bread Pepperoni Pizza
-- Global Sizzle --
Beef Pho Bo Bar
Vegetable Pho Chay Bar
-- Urban Kitchen --
Mashed Sweet Potatoes
Rotissere Porkloin w/Apricot Demi Glace
-- The Grill --
(GF) Marinated Grilled Chicken Breast
(V) Seasoned Wedge Fries
Chicken Tenders
-- Healthy Vegetarian Bar --
(V) Cut Corn
(V) Steamed Broccoli
(Vgn) Black Bean Tostadas
-- Desserts --
Bakery Parfait Bar
Chocolate 1/2 Sheet Cake
Chocolate Mousse
M & M Rice Krispy Treats
Oreo Cheesecake
Peach Maple Cobbler
Sugar Free Strawberry Orange Jell-O Gems
-----

【讨论】:

  • 哦。惊人的!比我的代码更短、更易读。这是我第一次使用 BeautifulSoup,非常感谢您的帮助!
【解决方案2】:

您可以通过它们在 HTML 中的深度来识别您的目标表。

这里有一些代码可以选择嵌套在深度 3 的表格:

tables = soup.findAll("table")
depth3 = []
for t in tables:
  if len(t.find_parents("table")) == 3:
    depth3.append(t)

这会为您的页面选择 6 个表格 - 三个用于标题(“早餐”、“午餐”、“晚餐”),三个用于菜单。它们交替出现 - 标题、菜单、标题、菜单等,因此您可以只处理位置 1、3 和 5 的表格。

您的解析现在应该容易多了。

【讨论】:

  • 成功了!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
相关资源
最近更新 更多