從零開始寫Python爬蟲 --- 爬蟲應用:今天吃什麼?

每天第四節課的時,我都會問我舍友:大哥,今天吃什麼?

吃什麼,對於很多選擇困難的小夥伴來說簡直太痛苦了

這裡乾脆就交給「老天爺」來決定吧!

爬取目標

本次爬的網站 美食傑meishij.net/

主要是看中了網站里有各種地區菜系的美食排行榜:

本來想試試看美團、餓了么之類的,

結果饒了一圈也沒找到相對應的排行榜單界面

在我的印象中是有這一類的網頁的啊?

難道因為被黃燜雞、骨頭飯、脆皮雞飯霸榜

所以取消了么? (逃~)

成果展示

一開始就是為了給公眾號加點新功能,

效果大概是這樣的:

歡迎小夥伴們來試試看呀

公眾號:findyourownway

一共抓取了1534道菜:

代碼相關

由於這個網站比較「中古」

沒有什麼反爬蟲的措施

所以寫起來十分簡單。加起來花了不到30分種

代碼的很短,關鍵部分我也都寫上注釋了,

應該沒有什麼不能理解的地方

需要說的就是其中用到了

  • Django的ORM
  • 生成器

Django 是一個很有名的Python Web框架

ORM 可以理解為:代碼和資料庫之前的中間層,他幫我們把代碼翻譯成資料庫可以理解的sql語言

yeild
是Python的生成器 關鍵詞,可以構造一個生成器,返回一個可迭代類型。Scrpay框架中就大量使用該設計

# 導入相關庫import requestsfrom bs4 import BeautifulSoup# 導入Django ormimport sysimport osimport djangosys.path.append(os.path.dirname( os.path.dirname(os.path.abspath(__file__))))os.environ["DJANGO_SETTINGS_MODULE"] = "django_project.settings"django.setup()# 導入Modelfrom SS.models import Foods# 排行榜入口urlTop_food_url = "http://top.meishi.cc/lanmu.php?cid=3"# 家常菜譜入口urlHome_food_url = "http://top.meishi.cc/lanmu.php?cid=13"# 中華菜系入口urlChina_food_url = "http://top.meishi.cc/lanmu.php?cid=2"# 外國菜入口urlForeign_food_url = "http://top.meishi.cc/lanmu.php?cid=10"def get_html_text(url): """獲取html文本""" try: r = requests.get(url, timeout=3) r.raise_for_status r.encoding = r.apparent_encoding return r.text except: return "error"def parse_city_id(url): """解析對應的城市排行榜連接""" res = [] html = get_html_text(url) # 做一個簡單的判斷 if html != "error": soup = BeautifulSoup(html, "lxml") # 定位到 全國各地特色小吃排行榜分類,<div> cityids = soup.find("div", class_="rank_content_top") for city in cityids.find_all("a"): res.append({"name": city.text, "url": city["href"]}) return res else: print("error !!!!")def parse_food_info(url): """解析對應的美食信息""" html = get_html_text(url) if html != "error": soup = BeautifulSoup(html, "lxml") # 定位到具體排行榜的位置 foods = soup.find("div", class_="rank_content_top10_wraper") # 開始解析信息 for food in foods.find_all("li"): # 尋找 食品名、做法鏈接、圖片鏈接 content = food.find("a", class_="img") name = content["title"] detial_url = content["href"] img_url = content.img["src"] print("正在解析美食:{}".format(name)) # 構造一個生成器,分別返回 食物名,做法鏈接,圖片鏈接 yield name, detial_url, img_url else: print("error !!!!")def save_data(name, cate, detail_url, img_url): """利用django orm 存儲記錄""" obj = Foods.objects.create( name=name, cate=cate, detail_link=detail_url, img_link=img_url) print("{}保存完畢".format(name))def main(): """程序入口""" # 構造所有起始url列表 url_list = [Top_food_url, Home_food_url, China_food_url, Foreign_food_url] # 找到所有城市排行榜的url for url in url_list: # 找到該分類下的所有cid res = parse_city_id(url) for page in res: # 找到菜系名稱 cate = page["name"] # 利用生成器迭代返回結果 for food_name, detail_url, img_url in parse_food_info(page["url"]): # save data # 用try except結構 防止菜名重複 try: save_data(food_name, cate, detail_url, img_url) except: passdef get_random_food(): """從資料庫隨機抓取菜品""" food = Foods.objects.order_by("?")[0] text = "名字:{}

菜系:{}

做法:{}

圖片:{}

不滿意?再試一次".format( food.name, food.cate, food.detail_link, food.img_link) return text

代碼跑起來是這樣的:

總結:

少吃點外賣!

每天的學習記錄都會 同步更新到:

微信公眾號: findyourownway

知乎專欄:zhuanlan.zhihu.com/Ehco

blog : www.ehcoblog.ml

Github: github.com/Ehco1996/Pyt


推薦閱讀:

圖中黃黑相間的是什麼品種的蜘蛛?

TAG:Python | 爬虫 | 美食 |