2017-07-31 170 views
1

我會先說我對Python有點新鮮。我最近在Slack機器人上工作,這裏是我目前所處的位置。在BS4中使用findAll創建列表

source = requests.get(url).content 
soup = BeautifulSoup(source, 'html.parser') 
price = soup.findAll("a", {"class":"pricing"})["quantity"] 

這是我試圖抓取的HTML代碼。

<a class="pricing" saleprice="240.00" quantity="1" added="2017-01-01"> S </a> 
<a class="pricing" saleprice="21.00" quantity="5" added="2017-03-14"> M </a> 
<a class="pricing" saleprice="139.00" quantity="19" added="2017-06-21"> L </a> 

當我只用soup.find(),我能找到的第一個量值,但我需要一個列表中所有的人。我考慮使用不同的庫,如lxml而不是bs4,但沒有任何運氣。任何幫助真的很感激,因爲我已經花了很長時間在這個。

+0

只需注意''.findAll'確實只是爲了向後兼容,我相信在leui中不推薦使用更多的Python-y命名約定。我建議使用'.find_all'移動foward。 –

回答

2

findAll方法返回一個bs4 Tag元素的列表,因此您不能直接選擇屬性。但是,您可以使用簡單的列表理解從迭代中的項中選擇屬性。

price = [a.get("quantity") for a in soup.findAll("a", {"class":"pricing"})] 

請注意,這是最好的時候訪問屬性,因爲它返回None(或者你可以設置默認值),如果該鍵不在attrs字典中使用get

正如Jon Clements所指出的,如果您不希望您的清單有None項目,以防某些項目沒有「數量」屬性,您可以按'class'和'quantity'進行過濾。

price = [a["quantity"] for a in soup.find_all("a", {"class":"pricing", "quantity":True})] 
+0

有些人可能會發現'soup.select('a.pricing')'更具可讀性......您也可以過濾掉非價格元素,例如:'[a ['quantity'] for a soup .find_all(「a」,class _ ='pricing',quantity = True)]' –

+0

是的,但我更喜歡'get'方法,這很簡單。儘管你對'select'和'find_all'完全正確。 –

+0

如果你想要一個默認值和一致的結果長度,'.get'是有意義的。如果不需要空值,則過濾有意義。取決於用例 - 只是指出了後面的選項。 –