【问题标题】:Parsing through python using beautiful soup使用漂亮的汤通过python解析
【发布时间】:2015-07-03 18:52:31
【问题描述】:

我正在尝试解析一家结构不佳的餐厅网站,并仅打印出菜单标题,例如:

“便当盒”, “Bara Chirashi 套装”, 等等

我正在使用 Python 库 Beautiful Soup,但无法获得正确的输出:

import requests
from bs4 import BeautifulSoup

url = ('http://www.sushitaro.com/menu-lunch.html')
r = requests.get(url, auth=('user', 'pass'))

data = r.text

soup = BeautifulSoup(data)
dataList = list()

for string in soup.findAll('b'):
    dataList.append(string)

print(dataList)

这会返回太多元素,它们以 HTML 的形式返回,而不仅仅是文本,而且文本内容本身非常混乱,带有 unicode 字符和过多的空格。

我真的遇到了麻烦,所以任何帮助都将不胜感激。

【问题讨论】:

  • “遇到麻烦”是什么意思?这有什么问题?看起来您正在尝试选择所有粗体文本;它不是那样做,还是那样做,但那不是你真正想做的?
  • 我认为您在使用此页面时会遇到问题,因为它的格式非常糟糕。此外,您不需要 coe 的 auth=(...) 部分,因为访问此页面不需要授权;)

标签: python html beautifulsoup screen-scraping


【解决方案1】:

我认为由于您的打印方式,输出可能难以辨认。

试试:

for d in dataList:
    print(d)

【讨论】:

    【解决方案2】:

    听起来您只是想从相关网站获取菜单项的名称。页面抓取可能很棘手,除了学习库之外,您还必须查看页面的结构。例如,这里的价格也是粗体的,所以如果你只想要菜单项的名称,你必须找到不同的区别特征。在这种情况下,网站设计者已将每个菜单标题的字体大小加一,因此,按照您的代码通过“汤”的定义,您可以获取所有且仅包含以下内容的菜单标题:

    import requests 
    from bs4 import BeautifulSoup
    url = ('http://www.sushitaro.com/menu-lunch.html')
    r = requests.get(url, auth=('user', 'pass'))
    data = r.text
    soup = BeautifulSoup(data)
    
    menuTitlesHTML = soup.findAll('font', {"size": "+1"})
    

    现在,这将返回大量 HTML 而不仅仅是文本。我假设您熟悉 Python 列表推导,这在这里非常方便。如果你想要文本,你可以试试:

    menuTitlesDirty = [titleHTML.text for titleHTML in menuTitlesHTML]
    

    但现在您会注意到标题有很多多余的空格,包括 unicode,以及一些额外的字符,如“@s”。由于您似乎只想要 ASCII 菜单标题,我们可以简单地转换为 ASCII,忽略错误,以清理 unicode。为此,我们可以用一个空格替换正则表达式上的匹配项,该表达式捕获不需要的字符:换行符、空格和@s。为此,我们可以应用“.strip()”,删除字符串末尾的多余空格。总之就是:

    import re
    badChars = re.compile('[\s@]+')
    menuTitles = [badChars.sub(" ", dirtyTitle.encode('ascii', 'ignore')).strip() for dirtyTitle in menuTitlesDirty]
    

    这会返回您建议的内容:

    ['Lunch Bento Box',
     'Bara Chirashi set',
     'Tekka Chirashi set',
     'Sushi Mori set',
     'Sushi Jo set',
     'Sushi Tokujo set',
     'Sashimi & Tempura Teishoku',
     'Tokujo Sashimi',
     "Today's Lunch Special",
     'Saba Shioyaki Teishoku',
     'Katsu Don set',
     'Tem Don set',
     'Cold Soba or Udon w/one topping',
     'Hot Soup Udon or Soba w/one Topping']
    

    总结一下:页面抓取是一个混乱且反复的过程,您希望利用页面上的任何差异来发挥自己的优势。 Python REPL 真的是你的朋友,在这里。希望这能让您和其他人对许多工具有所了解,更普遍地使用 Python,尤其是 Beautiful Soup,它们可以帮助完成这个过程。

    【讨论】:

    • 非常感谢,但我收到 AttributeError: 'str' object has no attribute 'text'
    • 我取出 .text.encoding('ascii', 'ignore') 一切都很好,除了第一个元素是“午餐便当盒”
    • 道歉:我现在添加了你的代码部分,@WakkaDroid,这是我自己所必需的,并纠正了一个错误:.encoding(...) 是必要的,但前面的 .text 是一个错误。
    猜你喜欢
    • 2013-03-21
    • 2017-05-23
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多