我正在尝试解析餐厅结构不佳的网站并打印出如下菜单标题:
“Bento Box”, “Bara Chirashi set”, 等
我正在使用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字符和多余的空格非常混乱。
我真的遇到了麻烦,所以任何帮助都会受到赞赏。
答案 0 :(得分:1)
听起来您只想从相关网站获取菜单项的名称。页面抓取可能很棘手,除了学习库之外,还必须查看页面的结构。例如,在这里,价格也是粗体,所以如果您只想要菜单项的名称,您必须找到不同的区别特征。在这种情况下,网站设计师已经为每个菜单标题增加了一个字体大小,因此,按照您的代码通过“汤”的定义,您可以获取所有菜单标题:
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,可以帮助完成这个过程。
答案 1 :(得分:0)
我认为输出可能因为你打印的方式而难以辨认。
尝试:
for d in dataList:
print(d)