摘要:注意爬豆爬一定要加入選項(xiàng),因?yàn)橹灰馕龅骄W(wǎng)站的有,就會(huì)自動(dòng)進(jìn)行過(guò)濾處理,把處理結(jié)果分配到相應(yīng)的類別,但偏偏豆瓣里面的為空不需要分配,所以一定要關(guān)掉這個(gè)選項(xiàng)。
選取什么網(wǎng)站來(lái)爬取呢?本課只針對(duì)python3環(huán)境下的Scrapy版本(即scrapy1.3+)
對(duì)于歪果人,上手練scrapy爬蟲的網(wǎng)站一般是官方練手網(wǎng)站 http://quotes.toscrape.com
我們中國(guó)人,當(dāng)然是用豆瓣Top250啦!https://movie.douban.com/top250
第一步,搭建準(zhǔn)備為了創(chuàng)造一個(gè)足夠干凈的環(huán)境來(lái)運(yùn)行scrapy,使用virtualenv是不錯(cuò)的選擇。
>>> mkdir douban250 && cd douban250 >>> virtualenv -p python3.5 doubanenv
首先要保證已經(jīng)安裝有virtualenv和python3.x版本,上面命令為創(chuàng)建python3.5環(huán)境的virtualenv
virtualenv教程:廖雪峰python教程-virtualenv
開啟virtualenv,并安裝scrapy
>>> source doubanenv/bin/activate >>> pip install scrapy
使用scrapy初始化項(xiàng)目一個(gè)項(xiàng)目,比如我們命名為douban_crawler
>>> scrapy startproject douban_crawler
這時(shí)生成了一個(gè)目錄結(jié)構(gòu)
douban_crawler/ douban.cfg douban_crawler/ __init__.py items.py middlewares.py piplines.py setting.py
并且命令行會(huì)給你一個(gè)提示:
You can start your first spider with: cd douban_crawler scrapy genspider example example.com
按提示執(zhí)行這兩步吧!
>>> cd douban_crawler >>> scrapy genspider douban movie.douban.com/top250
genspider后目錄結(jié)構(gòu)中增加了spider目錄
douban_crawler/ douban.cfg douban_crawler/ spiders/ __init__.py douban.py __init__.py items.py middlewares.py piplines.py setting.py在pycharm中設(shè)置好項(xiàng)目
首先,在pycharm中打開douban_crawler/
然后設(shè)置pycharm的虛擬環(huán)境:
Perference > Project:douban_crawler > Project Interpreter
點(diǎn)擊設(shè)置圖標(biāo)> Add Local > existing environment;把預(yù)置的python解析器,切換到剛剛創(chuàng)立的virtualenv下的doubanenv > bin > python3.5
準(zhǔn)備工作完成,可以開始爬取了!
打開spiders/目錄下的douban.py文件
# douban_crawler/ > spiders/ > douban.py import scrapy class DoubanSpider(scrapy.Spider): name = "douban" allowed_domains = ["movie.douban.com/top250"] start_urls = ["http://movie.douban.com/top250/"] def parse(self, response): pass
start_urls就是我們需要爬取的網(wǎng)址啦!
把start_urls中的http://movie.douban.com/top250/
改成https://movie.douban.com/top250/
接下來(lái)我們將改寫parse()函數(shù),進(jìn)行解析。
解析豆瓣250條目使用chrome或firefox瀏覽器打開https://movie.douban.com/top250/
使用右鍵菜單中的檢查(inspect)分析元素,可以看出:
".item"包裹了一個(gè)個(gè)詞條
每一個(gè)詞條下面
".pic a img"的src屬性包含了封面圖片地址
".info .hd a"的src屬性包含了豆瓣鏈接
".info .hd a .title"中的文字包含了標(biāo)題,因?yàn)槊總€(gè)電影會(huì)有多個(gè)別名,我們只用取第一個(gè)標(biāo)題就行了。
".info .bd .star .rating_num"包含了分?jǐn)?shù)
".info .bd .quote span.inq"包含了短評(píng)
另外導(dǎo)演、年代、主演、簡(jiǎn)介等信息需要點(diǎn)擊進(jìn)入條目的才能爬取,我們先爬取以上五條信息吧!
按照剛剛的解析,填寫parse()函數(shù)# douban_crawler/ > spiders/ > douban.py # -*- coding: utf-8 -*- import scrapy class DoubanSpider(scrapy.Spider): name = "douban" allowed_domains = ["movie.douban.com/top250"] start_urls = ["https://movie.douban.com/top250/"] def parse(self, response): items = response.css(".item") for item in items: yield { "cover_pic": item.css(".pic a img::attr(src)").extract_first(), "link": item.css(".info .hd a::attr(href)").extract_first(), "title": item.css(".info .hd a .title::text").extract_first(), "rating": item.css(".info .bd .star .rating_num::text").extract_first(), "quote": item.css(".info .bd .quote span.inq::text").extract_first() }
.css()運(yùn)行類似于jquery或pyquery的解析器,但它可以用::text或::attr(href)來(lái)直接獲取屬性或文字,應(yīng)當(dāng)說(shuō)比jquery解析器還要更方便。
當(dāng)然,.css只能返回一個(gè)對(duì)象,而需要具體的文字或?qū)傩裕瑒t需要.extract()或.extract_first()
其中.extract()返回所有符合條件的文字或?qū)傩詳?shù)組,而.extract_first()只返回查詢到的第一條文字或?qū)傩浴?/p> 在shell里驗(yàn)證解析語(yǔ)句是否正確
這里我們需要給大家一個(gè)竅門,就是先用shell驗(yàn)證剛剛寫的css對(duì)不對(duì)
在pycharm窗口左下方打開terminal
命令行輸入:
>>> scrapy shell https://movie.douban.com/top250
會(huì)出來(lái)一堆的返回信息,最后會(huì)出來(lái)一堆提示
[s] Available Scrapy objects: [s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc) [s] crawler[s] item {} [s] request [s] response <403 https://movie.douban.com/top250> [s] settings [s] spider [s] Useful shortcuts: [s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed) [s] fetch(req) Fetch a scrapy.Request and update local objects [s] shelp() Shell help (print this help) [s] view(response) View response in a browser
我們看到response一項(xiàng)
——什么?返回的403錯(cuò)誤?
原來(lái)我們爬取豆瓣沒(méi)有設(shè)置User-Agent請(qǐng)求頭,而豆瓣不接受無(wú)請(qǐng)求頭的Get請(qǐng)求,最終返回了403錯(cuò)誤。
這時(shí)趕緊在settings.py里面加入一行
# spider_crawler/ > settings.py USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
保存文件后,重新運(yùn)行
>>> scrapy shell https://movie.douban.com/top250
提示:
[s] response <200 https://movie.douban.com/top250>
這時(shí)就可以開始檢驗(yàn)剛剛的解析語(yǔ)句能不能獲得想要的結(jié)果了:
response.css(".item")
返回了一個(gè)
>>> items = response.css(".item") >>> item = item[0] #把cover_pic對(duì)應(yīng)的解析語(yǔ)句拷貝過(guò)來(lái) >>> item.css(".pic a img::attr(src)").extract_first()
返回
"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg"
即證明解析語(yǔ)句正確,其它的四項(xiàng)可以一一驗(yàn)證
>>> item.css(".pic a img::attr(src)").extract_first() "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" >>> item.css(".info .hd a::attr(href)").extract_first() "https://movie.douban.com/subject/1292052/" >>> item.css(".info .hd a .title::text").extract_first() "肖申克的救贖" >>> item.css(".info .bd .star .rating_num::text").extract_first() "9.6" >>> item.css(".info .bd .quote span.inq::text").extract_first() "希望讓人自由。"
這時(shí)候用exit()退出shell
再運(yùn)行爬蟲
>>> scrapy crawl douban
就可以看到解析后的數(shù)據(jù)輸出了!
翻頁(yè)爬取全部250條數(shù)據(jù)剛剛我們初步爬取了一下,但這一頁(yè)只顯示25條,如何通過(guò)翻頁(yè)爬到全部250條呢?
通過(guò)chrome瀏覽器的“檢查”功能,我們找到豆瓣頁(yè)面上的“下頁(yè)”所對(duì)應(yīng)的鏈接:
response.css(".paginator .next a::attr(href)")
現(xiàn)在我們改寫一個(gè)douban.py
# douban_crawler/ > spiders/ > douban.py class DoubanSpider(scrapy.Spider): name = "douban" allowed_domains = ["movie.douban.com/top250"] start_urls = ["https://movie.douban.com/top250"] def parse(self, response): items = response.css(".item") for item in items: yield { "cover_pic": item.css(".pic a img::attr(src)").extract_first(), "link": item.css(".info .hd a::attr(href)").extract_first(), "title": item.css(".info .hd a .title::text").extract_first(), "rating": item.css(".info .bd .star .rating_num::text").extract_first(), "quote": item.css(".info .bd .quote span.inq::text").extract_first() } next_page = response.css(".paginator .next a::attr(href)").extract_first() if next_page: next_page_real = response.urljoin(next_page) yield scrapy.Request(next_page_real, callback=self.parse,dont_filter=True)
以上通過(guò)response.urljoin()返回了拼接后的真實(shí)url
然后通過(guò)一個(gè)遞歸返回Request對(duì)象,遍歷了所有的頁(yè)面。
注意!爬豆爬一定要加入dont_filter=True選項(xiàng),因?yàn)閟crapy只要解析到網(wǎng)站的Url有"filter=",就會(huì)自動(dòng)進(jìn)行過(guò)濾處理,把處理結(jié)果分配到相應(yīng)的類別,但偏偏豆瓣url里面的filter為空不需要分配,所以一定要關(guān)掉這個(gè)選項(xiàng)。
這時(shí)再運(yùn)行一次爬蟲
>>> scrapy crawl douban
250條數(shù)據(jù)已經(jīng)爬取出來(lái)啦!
存儲(chǔ)數(shù)據(jù)到文件很簡(jiǎn)單,運(yùn)行爬蟲時(shí)加個(gè)-o就輸出啦!
>>> scrapy crawl douban -o douban.csv
于是你看到當(dāng)前目錄下多了一個(gè).csv文件,存儲(chǔ)的正是我們想要的結(jié)果!
你也可以用 .json .xml .pickle .jl 等數(shù)據(jù)類型存儲(chǔ),scrapy也是支持的!
利用Items把爬到的數(shù)據(jù)結(jié)構(gòu)化Scrapy的Item功能很類似于Django或其它mvc框架中的model作用,即把數(shù)據(jù)轉(zhuǎn)化成固定結(jié)構(gòu),這樣才能便出保存和展示。
我們打開 items.py文件,如下定義一個(gè)名為DoubanItem的數(shù)據(jù)類型。
# douban_clawler > items.py import scrapy class DoubanItem(scrapy.Item): title = scrapy.Field() link = scrapy.Field() rating = scrapy.Field() cover_pic = scrapy.Field() quote = scrapy.Field()
有了DoubanItem后,就可以改造douban.py里面的parse函數(shù),使爬取的信息全部轉(zhuǎn)化為Item形式啦
# -*- coding: utf-8 -*- import scrapy from douban_crawler.items import DoubanItem class DoubanSpider(scrapy.Spider): name = "douban" allowed_domains = ["movie.douban.com/top250"] start_urls = ["https://movie.douban.com/top250"] def parse(self, response): items = response.css(".item") for item in items: yield DoubanItem({ "cover_pic": item.css(".pic a img::attr(src)").extract_first(), "link": item.css(".info .hd a::attr(href)").extract_first(), "title": item.css(".info .hd a .title::text").extract_first(), "rating": item.css(".info .bd .star .rating_num::text").extract_first(), "quote": item.css(".info .bd .quote span.inq::text").extract_first() }) next_page = response.css(".paginator .next a::attr(href)").extract_first() if next_page: next_page_real = response.urljoin(next_page) yield scrapy.Request(next_page_real, callback=self.parse,dont_filter=True)
非常簡(jiǎn)單,只修改了兩行:
引入DoubanItem
原來(lái)yield的一個(gè)dict格式,現(xiàn)在直接在DoubanItem中傳入dict就可以把dict轉(zhuǎn)化成DoubanItem對(duì)象了!
現(xiàn)在你可以scrapy crawl douban再試一次爬取,看是不是已經(jīng)轉(zhuǎn)換成了DoubanItem形式了?
存儲(chǔ)數(shù)據(jù)到MongoDB有了DoubanItem數(shù)據(jù)結(jié)構(gòu),我們就可以保存進(jìn)MongoDB啦!
保存到MongoDB,我們需要用到pipline組件,沒(méi)錯(cuò),就是上面那一堆文件中的piplines.py
之前我們確保兩件事:
mongodb服務(wù)已經(jīng)開啟。如果沒(méi)有開啟請(qǐng)sudo mongod開啟本地。
pymongo包已安裝。如果沒(méi)有安裝請(qǐng)pip install pymongo
使用pipline,請(qǐng)記住四個(gè)字!
啟!(開啟爬蟲)對(duì)應(yīng)于open_spider,在spider開啟時(shí)調(diào)用
在這里面啟動(dòng)mongodb
承!(承接爬取任務(wù))對(duì)應(yīng)于from_clawler,它有幾個(gè)特點(diǎn):
它是類對(duì)象,所以必須加上@classmethod。
只要有這個(gè)函數(shù),它就一定會(huì)被調(diào)用。
它必須返回我們Pipline本身對(duì)象的實(shí)例。
它有進(jìn)入Scrapy所有核心組件的能力,也就是說(shuō)可以通過(guò)它訪問(wèn)到settings對(duì)象。
轉(zhuǎn)!(轉(zhuǎn)換對(duì)象)對(duì)應(yīng)于process_item,它有幾個(gè)特點(diǎn):
必須返回Item對(duì)象或raise DropItem()錯(cuò)誤
在這個(gè)函數(shù)內(nèi)將傳入爬取到的item并進(jìn)行其它操作。
合!(閉合爬蟲)于應(yīng)于close_spider,在spider關(guān)閉是調(diào)用
我們可以在這個(gè)函數(shù)內(nèi)關(guān)閉MongoDB
有了以上知道,我們上代碼!
# douban_crawler > piplines.py import pymongo class DoubanCrawlerPipeline(object): def __init__(self, mongo_uri, mongo_db): self.mongo_uri = mongo_uri self.mongo_db = mongo_db def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] @classmethod def from_crawler(cls, crawler): return cls( mongo_uri = crawler.settings.get("MONGO_URI"), mongo_db = crawler.settings.get("MONGO_DB") ) def process_item(self, item, spider): self.db["douban250"].insert_one(dict(item)) return item def close_spider(self, spider): self.client.close()
同時(shí)在setting中添加MONGODB的配置
MONGO_URI = "localhost" MONGO_DB = "douban"
還有非常重要的一步!
在setting中打開pipline的注釋!!
ITEM_PIPELINES = { "douban_crawler.pipelines.DoubanCrawlerPipeline": 300, }現(xiàn)在打開crawler
scrapy crawl douban
爬到的信息已經(jīng)保存到數(shù)據(jù)庫(kù)了!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41038.html
摘要:本文內(nèi)容爬取豆瓣電影頁(yè)面內(nèi)容,字段包含排名,片名,導(dǎo)演,一句話描述有的為空,評(píng)分,評(píng)價(jià)人數(shù),上映時(shí)間,上映國(guó)家,類別抓取數(shù)據(jù)存儲(chǔ)介紹爬蟲框架教程一入門創(chuàng)建項(xiàng)目創(chuàng)建爬蟲注意,爬蟲名不能和項(xiàng)目名一樣應(yīng)對(duì)反爬策略的配置打開文件,將修改為。 本文內(nèi)容 爬取豆瓣電影Top250頁(yè)面內(nèi)容,字段包含:排名,片名,導(dǎo)演,一句話描述 有的為空,評(píng)分,評(píng)價(jià)人數(shù),上映時(shí)間,上映國(guó)家,類別 抓取數(shù)據(jù)存儲(chǔ) ...
摘要:這次我們爬取的內(nèi)容準(zhǔn)備步驟找到格式網(wǎng)頁(yè)中需要爬取的數(shù)據(jù)的例如我們需要爬取圖片的這里用的是不會(huì)用的同學(xué)請(qǐng)百度然后我們開始建立工程打開然后在你想要建立工程的目錄下面輸入就會(huì)自動(dòng)建立一個(gè)工程然后去根目錄建立一個(gè)去這個(gè)目錄里建立一個(gè)注意這里的主爬蟲 這次我們爬取的內(nèi)容 showImg(https://segmentfault.com/img/bVSirX?w=1021&h=521); 準(zhǔn)備步驟...
摘要:前言新接觸爬蟲,經(jīng)過(guò)一段時(shí)間的實(shí)踐,寫了幾個(gè)簡(jiǎn)單爬蟲,爬取豆瓣電影的爬蟲例子網(wǎng)上有很多,但都很簡(jiǎn)單,大部分只介紹了請(qǐng)求頁(yè)面和解析部分,對(duì)于新手而言,我希望能夠有一個(gè)比較全面的實(shí)例。 0.前言 新接觸爬蟲,經(jīng)過(guò)一段時(shí)間的實(shí)踐,寫了幾個(gè)簡(jiǎn)單爬蟲,爬取豆瓣電影的爬蟲例子網(wǎng)上有很多,但都很簡(jiǎn)單,大部分只介紹了請(qǐng)求頁(yè)面和解析部分,對(duì)于新手而言,我希望能夠有一個(gè)比較全面的實(shí)例。所以找了很多實(shí)例和文...
摘要:介紹在博客爬蟲爬取豆瓣電影圖片中我們利用的爬蟲框架,將豆瓣電影圖片下載到自己電腦上。那么,在的爬蟲的也可以下載圖片嗎答案當(dāng)然是肯定的在本次分享中,我們將利用的包和函數(shù)來(lái)實(shí)現(xiàn)圖片的下載。 介紹 ??在博客:Scrapy爬蟲(4)爬取豆瓣電影Top250圖片中我們利用Python的爬蟲框架Scrapy,將豆瓣電影Top250圖片下載到自己電腦上。那么,在Java的爬蟲的也可以下載圖片嗎?答...
摘要:楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲技術(shù)以供學(xué)習(xí),。本文來(lái)源知乎作者路人甲鏈接楚江數(shù)據(jù)提供網(wǎng)站數(shù)據(jù)采集和爬蟲軟件定制開發(fā)服務(wù),服務(wù)范圍涵蓋社交網(wǎng)絡(luò)電子商務(wù)分類信息學(xué)術(shù)研究等。 楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲技術(shù)以供學(xué)習(xí),http://www.chujiangdata.com。 第一:Python爬蟲學(xué)習(xí)系列教程(來(lái)源于某博主:htt...
閱讀 2209·2021-11-22 15:29
閱讀 4098·2021-11-04 16:13
閱讀 991·2019-08-29 16:58
閱讀 339·2019-08-29 16:08
閱讀 1457·2019-08-23 17:56
閱讀 2378·2019-08-23 17:06
閱讀 3166·2019-08-23 16:55
閱讀 2058·2019-08-23 16:22