用美丽的汤提取可变元素

时间:2018-04-18 10:52:32

标签: python beautifulsoup

我正试图刮掉yelp餐厅的评级,没有运气。我正在使用美丽的汤来做到这一点

基本上,源代码如下所示:

<div class="i-stars i-stars--regular-5 rating-large" title="5.0 star rating">
    <img class="offscreen" height="303" src="https://s3-media2.fl.yelpcdn.com/assets/srv0/yelp_design_web/9b34e39ccbeb/assets/img/stars/stars.png" width="84" alt="5.0 star rating">
</div>

正如你所看到的,课程名称会根据评分进行更改,因此我尝试与我的查找功能进行某种“部分”匹配

rating = r.find_all('div', {'class':'i-stars i-stars--regular'}).get('title', 'No title attribute')
print(rating)

但它似乎不起作用。

4 个答案:

答案 0 :(得分:1)

使用regex -

import re
rating = [x.get('title', 'No title attribute') for x in r.find_all('div', attrs={"class": re.compile("i-stars i-stars--regular-")})]
print(rating)

答案 1 :(得分:0)

如果您需要部分搜索课程使用。

s = """<div class="i-stars i-stars--regular-5 rating-large" title="5.0 star rating">
    <img class="offscreen" height="303" src="https://s3-media2.fl.yelpcdn.com/assets/srv0/yelp_design_web/9b34e39ccbeb/assets/img/stars/stars.png" width="84" alt="5.0 star rating">
</div>"""

from bs4 import BeautifulSoup
r = BeautifulSoup(s, "html.parser")
rating = r.find_all('div')
for i in rating:
    if "i-stars i-stars--regular-5" in " ".join(i["class"]):
        print(i.get('title', 'No title attribute')) 

<强>输出:

5.0 star rating

答案 2 :(得分:0)

您可以使用以下功能执行此操作:

from bs4 import BeautifulSoup
import re
html_text = '<div class="i-stars i-stars--regular-5 rating-large" title="5.0 star rating">\n    <img class="offscreen" height="303" src="https://s3-media2.fl.yelpcdn.com/assets/srv0/yelp_design_web/9b34e39ccbeb/assets/img/stars/stars.png" width="84" alt="5.0 star rating">\n</div'
soup = BeautifulSoup(html_text, 'html.parser')
soup.find_all(class_ = lambda x:re.search(r"i\-stars i\-stars\-\-regular\-\d rating\-\w+",x))

根据您的要求在其中提供正则表达式模式。在这里,我已将其标记为任何评级大小和明星。

答案 3 :(得分:0)

find_all()返回所有匹配项的列表。因此,您可以在列表中使用.get()。要只获得一个项目,您必须使用find_all(...)[0],或者更好的是使用find()函数;返回第一场比赛。

此外,由于类名根据评级而变化,因此您可以使用常量类并将其添加到列表中。例如,i-startsrating-large似乎是常量。所以,你可以使用这个:

html = '''
<div class="i-stars i-stars--regular-5 rating-large" title="5.0 star rating">
    <img class="offscreen" height="303" src="https://s3-media2.fl.yelpcdn.com/assets/srv0/yelp_design_web/9b34e39ccbeb/assets/img/stars/stars.png" width="84" alt="5.0 star rating">
</div>'''
soup = BeautifulSoup(html, 'lxml')
rating = soup.find('div', {'class': ['i-stars', 'rating-large']}).get('title', 'No title attribute')
print(rating)
# 5.0 star rating

但是,在列表中使用类时必须要小心,因为它也会匹配只有一个类的类,例如class="i-stars"。如果存在这种情况,您可以使用以下选择器:

ratings = soup.select_one('div.i-stars.rating-large').get('title', 'No title attribute')