簡體   English   中英

用美麗的湯提取可變元素

[英]Extracting variable element with beautiful soup

我正在努力提高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>

如您所見,類名在給定等級的情況下會發生變化,因此我試圖與我的find函數進行某種“部分”匹配

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

但這似乎不起作用。

使用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)

如果您需要部分搜索以用於班級使用。

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

您可以通過使用一個函數來做到這一點:

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))

根據您的要求給出一個正則表達式模式。 在這里,我已將其標記為任何額定大小和星級。

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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM