項(xiàng)目目標(biāo):
爬取熱門(mén)菜譜清單络断,獲取菜名射亏、原材料和詳細(xì)烹飪流程的URL
步驟與思路:
第一:打開(kāi)網(wǎng)址谜嫉,查閱robots協(xié)議
1湘纵、網(wǎng)址:http://www.xiachufang.com/explore/
2返弹、它的robots協(xié)議:http://www.xiachufang.com/robots.txt
閱讀這個(gè)robots協(xié)議會(huì)發(fā)現(xiàn):我們要爬取的/explore/不在禁止爬取的列表內(nèi)锈玉,但如果要爬取/recipe/服務(wù)器就會(huì)不歡迎。在網(wǎng)頁(yè)里琉苇,recipe是每一道菜的詳情頁(yè)面嘲玫,記錄了這道菜的做法,所以不去碰它并扇。
第二:ctrl+shift+i查找和定位
1去团、 菜名和URL:<p class=’name’>下的<a>標(biāo)簽
提取<a>標(biāo)簽,用text拿到它的文本穷蛹,再使用[href]獲取到URL
2土陪、 食材:<p class="ing ellipsis">
3、 根據(jù)菜名的路徑肴熏、URL的路徑鬼雀、食材的路徑,我們可以這三者的最小共同父級(jí)標(biāo)簽蛙吏,是:<div class="info pure-u">
第三:思路
思路一:先去爬取所有的最小父級(jí)標(biāo)簽<div class="info pure-u">源哩,然后針對(duì)每一個(gè)父級(jí)標(biāo)簽鞋吉,想辦法提取里面的菜名、URL励烦、食材谓着。
思路二:分別提取所有的菜名、所有的URL坛掠、所有的食材赊锚。然后讓菜名、URL屉栓、食材給一一對(duì)應(yīng)起來(lái)(把數(shù)據(jù)存到列表里:每一組菜名舷蒲、URL、食材是一個(gè)小列表友多,小列表組成一個(gè)大列表牲平。第0個(gè)菜名,對(duì)應(yīng)第0個(gè)URL夷陋,對(duì)應(yīng)第0組食材欠拾,按順序走即可。如下:
[[菜A,URL_A,食材A],[菜B,URL_B,食材B],[菜C,URL_C,食材C]])
代碼編寫(xiě)
思路一(先爬最小父級(jí)標(biāo)簽)的寫(xiě)法:
import requests# 引用requests庫(kù)
from bs4 import BeautifulSoup# 引用BeautifulSoup庫(kù)
res_foods = requests.get('http://www.xiachufang.com/explore/')# 獲取數(shù)據(jù)
bs_foods = BeautifulSoup(res_foods.text,'html.parser')# 解析數(shù)據(jù)
list_foods = bs_foods.find_all('div',class_='info pure-u')# 查找最小父級(jí)標(biāo)簽
list_all = []# 創(chuàng)建一個(gè)空列表骗绕,用于存儲(chǔ)信息
for food in list_foods:
tag_a = food.find('a') # 提取food中的<a>標(biāo)簽
name = tag_a.text[17:-13] # 菜名藐窄,使用[17:-13]切掉了多余的信息
URL = 'http://www.xiachufang.com'+tag_a['href'] # 獲取URL
tag_p = food.find('p',class_='ing ellipsis') # 提取food中的<p>標(biāo)簽
ingredients = tag_p.text[1:-1] # 食材,使用[1:-1]切掉了多余的信息
list_all.append([name,URL,ingredients]) # 將菜名酬土、URL荆忍、食材,封裝為列表撤缴,添加進(jìn)list_all
print(list_all)
需要注意__獲取標(biāo)簽里純文本信息的方法:
查找標(biāo)簽(比如<p>)刹枉,然后使用text提取<p>標(biāo)簽里的純文本信息就可以了。在用text獲取純文本時(shí)屈呕,獲取的是該標(biāo)簽內(nèi)的所有純文本信息微宝,不論是直接在這個(gè)標(biāo)簽內(nèi),還是在它的子標(biāo)簽內(nèi)虎眨。
需要強(qiáng)調(diào)的是蟋软,如果是要提取屬性的值,text是不可以的嗽桩。父標(biāo)簽只能提取它自身的屬性值岳守,不能提取子標(biāo)簽的屬性值。比如:
bs = BeautifulSoup('<p><a )
tag = bs.find('p')
print(tag['href'])# 這樣會(huì)報(bào)錯(cuò)碌冶,因?yàn)?lt;p>標(biāo)簽沒(méi)有屬性href湿痢,href屬于<a>標(biāo)簽
思路二(分別提取,匯總列表)的寫(xiě)法:
import requests# 引用requests庫(kù)
from bs4 import BeautifulSoup# 引用BeautifulSoup庫(kù)
res_foods = requests.get('http://www.xiachufang.com/explore/')# 獲取數(shù)據(jù)
bs_foods = BeautifulSoup(res_foods.text,'html.parser')# 解析數(shù)據(jù)
tag_name = bs_foods.find_all('p',class_='name')# 查找包含菜名和URL的<p>標(biāo)簽
tag_ingredients = bs_foods.find_all('p',class_='ing ellipsis')# 查找包含食材的<p>標(biāo)簽
list_all = []# 創(chuàng)建一個(gè)空列表扑庞,用于存儲(chǔ)信息
for x in range(len(tag_name)):# 啟動(dòng)一個(gè)循環(huán)譬重,次數(shù)等于菜名的數(shù)量
list_food = [tag_name[x].text[18:-14],tag_name[x].find('a')['href'],tag_ingredients[x].text[1:-1]] # 提取信息拒逮,封裝為列表。注意此處[18:-14]切片和之前不同臀规,是因?yàn)榇颂幨褂玫氖?lt;p>標(biāo)簽消恍,而之前是<a>
list_all.append(list_food) # 將信息添加進(jìn)list_all
print(list_all)