Python爬蟲系列(四): Project 1:下廚房(Web端)

實戰(zhàn)第一篇笋轨,以下廚房網(wǎng)頁端為例,任務(wù)目標(biāo):

  1. 爬取下廚房網(wǎng)頁端所有的菜品
  2. 創(chuàng)建基本的工具類走孽,數(shù)據(jù)管理工具
  3. 將爬取的數(shù)據(jù)結(jié)構(gòu)化保存到數(shù)據(jù)庫中

以下是下廚房的首頁:

屏幕快照 2017-07-01 下午12.09.13.png

從網(wǎng)頁結(jié)構(gòu)上分析,分類是個很好的爬取所有菜品的入口,點開菜譜分類:

屏幕快照 2017-07-01 下午12.12.28.png

點擊其中一個分類:

屏幕快照 2017-07-01 下午12.13.45.png

到此术陶,基本思路已經(jīng)很清晰:

  1. 爬取所有的分類
  2. 通過分類進(jìn)入菜品列表,爬取該分類下所有菜品

難點有兩個:

  1. 分類頁有個【展開全部】的action煤痕,如何得到一個大分類下的所有二級分類梧宫?
  2. 如何爬取一個二級分類下的所有頁數(shù)據(jù)?

問題1

打開瀏覽器摆碉,查看分類頁面的源碼:

屏幕快照 2017-07-01 下午12.25.02.png

不難發(fā)現(xiàn)祟敛,點擊『展開全部』后隱藏的數(shù)據(jù)都是存放在<div class='cates-list-all clearfix hidden'>下的,只要取該div下的數(shù)據(jù)兆解,變可以得到全量的分類馆铁,其結(jié)構(gòu)如下圖:

image.png

到此問題1已解決

問題2

首先查看分頁部分的源代碼:

image.png

只要從每頁中取出下一頁的鏈接,依次爬取每一頁的內(nèi)容即可锅睛,知道下一頁的鏈接為空時埠巨,及表示已是最后一頁,該二級分類下的所有菜品都爬完了现拒。

開始寫代碼

1. 創(chuàng)建project
scrapy startproject cook

文件結(jié)構(gòu)

(env) ?  cook tree
.
├── scrapy.cfg
└── cook
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── settings.py
    └── spiders
        └── __init__.py

2 directories, 7 files

關(guān)于scrapy的基本內(nèi)容這里不多做介紹辣垒,不熟悉的同學(xué)可以查閱本系列第二篇文章:Python爬蟲系列(三):python scrapy介紹和使用

2. 創(chuàng)建分類表結(jié)構(gòu)
        command = (
            "CREATE TABLE IF NOT EXISTS {} ("
            "`id` INT(8) NOT NULL AUTO_INCREMENT,"
            "`name` CHAR(20) NOT NULL COMMENT '分類名稱',"
            "`url` TEXT NOT NULL COMMENT '分類url',"
            "`category` CHAR(20) NOT NULL COMMENT '父級分類',"
            "`category_id` INT(8) NOT NULL COMMENT '分類id',"
            "`create_time` DATETIME NOT NULL,"
            "PRIMARY KEY(id),"
            "UNIQUE KEY `category_id` (`category_id`)"
            ") ENGINE=InnoDB".format(config.category_urls_table)
        )

        self.sql.create_table(command)
3. 解析部分
    def parse_all(self, response):
        if response.status == 200:
            file_name = '%s/category.html' % (self.dir_name)
            self.save_page(file_name, response.body)
            categorys = response.xpath("http://div[@class='cates-list-all clearfix hidden']").extract()
            for category in categorys:
                sel_category = Selector(text = category)
                category_father = sel_category.xpath("http://h4/text()").extract_first().strip()
                items = sel_category.xpath("http://ul/li/a").extract()
                for item in items:
                    sel = Selector(text = item)
                    url = sel.xpath("http://@href").extract_first()
                    name = sel.xpath("http://text()").extract_first()
                    _id = re.compile('/category/(.*?)/').findall(url)[0]
                    dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    msg = (None , name, url, category_father, _id, dt)
                    command = ("INSERT IGNORE INTO {} "
                                "(id, name, url, category, category_id, create_time)"
                                "VALUES(%s,%s,%s,%s,%s,%s)".format(config.category_urls_table)
                    )
                    self.sql.insert_data(command, msg)

根據(jù)問題1里面的描述,我們要從http://www.xiachufang.com/category/中找出所有的二級分類以及其連接印蔬,每個一級分類對應(yīng)的數(shù)據(jù)都在<div class='cates-list-all clearfix hidden'>下勋桶,參考代碼:
categorys = response.xpath("http://div[@class='cates-list-all clearfix hidden']").extract()
接著我們將所有二級分類的名稱,對應(yīng)url取出存入數(shù)據(jù)中。

4.爬取菜品

先取出之前存儲到數(shù)據(jù)控的所有分類:

        command = "SELECT * from {}".format(config.category_urls_table)
        data = self.sql.query(command)

解析部分:

    def parse_all(self, response):
        utils.log(response.url)
        if response.status == 200:
            file_name = '%s/category.html' % (self.dir_name)
            self.save_page(file_name, response.body)
            recipes = response.xpath("http://div[@class='normal-recipe-list']/ul/li").extract()
            self.parse_recipes(recipes)
            nextPage = response.xpath("http://div[@class='pager']/a[@class='next']/@href").extract_first()
            if nextPage:
                yield Request(
                    url = self.base_url + nextPage,
                    headers = self.header,
                    callback = self.parse_all,
                    errback = self.error_parse,
                )

    def parse_recipes(self, recipes):
        for recipe in recipes:
            sel = Selector(text = recipe)
            name = sel.xpath("http://p[@class='name']/text()").extract_first().strip()
            url = sel.xpath("http://a[1]/@href").extract_first()
            img = sel.xpath("http://div[@class='cover pure-u']/img/@data-src").extract_first()
            item_id = re.compile("/recipe/(.*?)/").findall(url)[0]
            source = sel.xpath("http://p[@class='ing ellipsis']/text()").extract_first().strip()
            score = sel.xpath("http://p[@class='stats']/span/text()").extract_first().strip()
            dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            msg = (None, name, url, img, item_id, source, score, dt)
            command = ("INSERT IGNORE INTO {} "
                        "(id, name, url, img, item_id, source, score, create_time)"
                        "VALUES(%s,%s,%s,%s,%s,%s,%s,%s)".format(config.item_list_table)
            )
            self.sql.insert_data(command, msg)

通過分析源代碼例驹,先取出每一頁的所有菜品信息部分:

recipes = response.xpath("http://div[@class='normal-recipe-list']/ul/li").extract()

通過方法parse_recipes解析出該頁所有的菜品信息捐韩,并存儲。
同時取出『下一頁』對應(yīng)的url(nextPage),如果nextPage不為空(還有下一頁)鹃锈,則接著爬取下一頁內(nèi)容荤胁。

5.執(zhí)行爬蟲程序

依次執(zhí)行以上的兩個spider程序,下廚房所有的菜品就到手了屎债,有興趣的同學(xué)也可以接著爬取菜品的詳情頁內(nèi)容仅政。

屏幕快照 2017-07-01 下午1.05.23.png
屏幕快照 2017-07-01 下午1.05.31.png

源碼地址:https://github.com/sam408130/xcf_crawler
交流學(xué)習(xí)qq:197329984

再次聲明,本篇文章僅用于交流學(xué)習(xí)盆驹,請勿用于任何商業(yè)用途

接下來文章內(nèi)容預(yù)告:

  1. 如果爬取京東app(https通信)數(shù)據(jù)
  2. 如何添加代理
  3. scrapy的管理圆丹,部署
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市躯喇,隨后出現(xiàn)的幾起案子辫封,更是在濱河造成了極大的恐慌,老刑警劉巖玖瘸,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秸讹,死亡現(xiàn)場離奇詭異,居然都是意外死亡雅倒,警方通過查閱死者的電腦和手機(jī)璃诀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔑匣,“玉大人劣欢,你說我怎么就攤上這事〔昧迹” “怎么了凿将?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長价脾。 經(jīng)常有香客問我牧抵,道長,這世上最難降的妖魔是什么侨把? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任犀变,我火速辦了婚禮,結(jié)果婚禮上秋柄,老公的妹妹穿的比我還像新娘获枝。我一直安慰自己,他們只是感情好骇笔,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布省店。 她就那樣靜靜地躺著嚣崭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪懦傍。 梳的紋絲不亂的頭發(fā)上雹舀,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機(jī)與錄音谎脯,去河邊找鬼葱跋。 笑死持寄,一個胖子當(dāng)著我的面吹牛源梭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稍味,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼废麻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了模庐?” 一聲冷哼從身側(cè)響起烛愧,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掂碱,沒想到半個月后怜姿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡疼燥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年沧卢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醉者。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡但狭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撬即,到底是詐尸還是另有隱情立磁,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布剥槐,位于F島的核電站唱歧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粒竖。R本人自食惡果不足惜颅崩,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望温圆。 院中可真熱鬧挨摸,春花似錦、人聲如沸岁歉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熔掺,卻和暖如春饱搏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背置逻。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工推沸, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人券坞。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓鬓催,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恨锚。 傳聞我的和親對象是個殘疾皇子宇驾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. 概述 本文主要介紹網(wǎng)絡(luò)爬蟲,采用的實現(xiàn)語言為Python猴伶,目的在于闡述網(wǎng)絡(luò)爬蟲的原理和實現(xiàn)课舍,并且對目前常見的...
    Lemon_Home閱讀 2,731評論 0 21
  • 本文分享的大體框架包含以下三部分 (1)首先介紹html網(wǎng)頁,用來解析html網(wǎng)頁的工具xpath(2)介紹pyt...
    不忘初心c閱讀 2,546評論 0 14
  • 這個項目也是初窺python爬蟲的一個項目他挎,也是我的畢業(yè)設(shè)計筝尾,當(dāng)時選題的時候,發(fā)現(xiàn)大多數(shù)人選擇的都是網(wǎng)站類办桨,實在是...
    夢航韓語閱讀 2,989評論 2 37
  • 背景 部門(東方IC筹淫、圖蟲)業(yè)務(wù)驅(qū)動,需要搜集大量圖片資源崔挖,做數(shù)據(jù)分析贸街,以及正版圖片維權(quán)。前期主要用node做爬蟲...
  • 梁思成(1901-1972)狸相,中國建筑史學(xué)家薛匪,建筑師,城市規(guī)劃師和教育家脓鹃,一生致力于保護(hù)中國古代建筑和文化遺產(chǎn)逸尖。曾...
    MarkShen閱讀 923評論 0 0