摘要:因?yàn)闀簳r(shí)還沒有學(xué)到如何模擬登陸,所以我就先抓像豆瓣這樣不需要登陸的網(wǎng)站上的內(nèi)容。其中會(huì)回調(diào)函數(shù),用是因?yàn)槎拱陥D書并不是格式一致的。只需要在中設(shè)置項(xiàng)目代碼地址豆瓣圖書爬蟲
前言
Scrapy學(xué)習(xí)(一) 安裝
Scrapy學(xué)習(xí)(二) 入門
有了前兩篇的基礎(chǔ),就可以開始互聯(lián)網(wǎng)上爬取我們感興趣的信息了。因?yàn)闀簳r(shí)還沒有學(xué)到如何模擬登陸,所以我就先抓像豆瓣這樣不需要登陸的網(wǎng)站上的內(nèi)容。
我的開發(fā)環(huán)境是 Win7 + PyChram + Python3.5 + MongoDB
爬蟲的目標(biāo)是豆瓣的日本文學(xué)標(biāo)簽下的所有書籍基本信息
scrapy startproject douban
接著移動(dòng)到douban目錄下
scrapy genspider book book.douban.com
在spider目錄下生成相應(yīng)的BookSpider模板
編寫Item在items.py中編寫我們需要的數(shù)據(jù)模型
class BookItem(scrapy.Item): book_name = scrapy.Field() book_star = scrapy.Field() book_pl = scrapy.Field() book_author = scrapy.Field() book_publish = scrapy.Field() book_date = scrapy.Field() book_price = scrapy.Field()編寫Spider
訪問豆瓣的日本文學(xué)標(biāo)簽,將url的值寫到start_urls中。接著在Chrome的幫助下,可以看到每本圖書是在ul#subject-list > li.subject-item
class BookSpider(scrapy.Spider): ... def parse(self, response): sel = Selector(response) book_list = sel.css("#subject_list > ul > li") for book in book_list: item = BookItem() item["book_name"] = book.xpath("div[@class="info"]/h2/a/text()").extract()[0].strip() item["book_star"] = book.xpath("div[@class="info"]/div[2]/span[@class="rating_nums"]/text()").extract()[ 0].strip() item["book_pl"] = book.xpath("div[@class="info"]/div[2]/span[@class="pl"]/text()").extract()[0].strip() pub = book.xpath("div[@class="info"]/div[@class="pub"]/text()").extract()[0].strip().split("/") item["book_price"] = pub.pop() item["book_date"] = pub.pop() item["book_publish"] = pub.pop() item["book_author"] = "/".join(pub) yield item
測(cè)試一下代碼是否有問題
scrapy crawl book -o items.json
奇怪的發(fā)現(xiàn),items.json內(nèi)并沒有數(shù)據(jù),后頭看控制臺(tái)中的DEBUG信息
2017-02-04 16:15:38 [scrapy.core.engine] INFO: Spider opened
2017-02-04 16:15:38 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-02-04 16:15:38 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-02-04 16:15:39 [scrapy.core.engine] DEBUG: Crawled (403)2017-02-04 16:15:39 [scrapy.core.engine] DEBUG: Crawled (403)
爬取網(wǎng)頁(yè)時(shí)狀態(tài)碼是403。這是因?yàn)榉?wù)器判斷出爬蟲程序,拒絕我們?cè)L問。
我們可以在settings中設(shè)定USER_AGENT的值,偽裝成瀏覽器訪問頁(yè)面。
USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
再試一次,就發(fā)現(xiàn)items.json有值了。但仔細(xì)只有第一頁(yè)的數(shù)據(jù),如果我們想要爬取所有的數(shù)據(jù),就需要爬完當(dāng)前頁(yè)后自動(dòng)獲得下一頁(yè)的url,以此類推爬完所有數(shù)據(jù)。
所以我們對(duì)spider進(jìn)行改造。
... def parse(self, response): sel = Selector(response) book_list = sel.css("#subject_list > ul > li") for book in book_list: item = BookItem() try: item["book_name"] = book.xpath("div[@class="info"]/h2/a/text()").extract()[0].strip() item["book_star"] = book.xpath("div[@class="info"]/div[2]/span[@class="rating_nums"]/text()").extract()[0].strip() item["book_pl"] = book.xpath("div[@class="info"]/div[2]/span[@class="pl"]/text()").extract()[0].strip() pub = book.xpath("div[@class="info"]/div[@class="pub"]/text()").extract()[0].strip().split("/") item["book_price"] = pub.pop() item["book_date"] = pub.pop() item["book_publish"] = pub.pop() item["book_author"] = "/".join(pub) yield item except: pass nextPage = sel.xpath("http://div[@id="subject_list"]/div[@class="paginator"]/span[@class="next"]/a/@href").extract()[0].strip() if nextPage: next_url = "https://book.douban.com"+nextPage yield scrapy.http.Request(next_url,callback=self.parse)
其中scrapy.http.Request會(huì)回調(diào)parse函數(shù),用try...catch是因?yàn)槎拱陥D書并不是格式一致的。遇到有問題的數(shù)據(jù),就拋棄不用。
突破反爬蟲一般來(lái)說,如果爬蟲速度過快。會(huì)導(dǎo)致網(wǎng)站拒絕我們的訪問,所以我們需要在settings設(shè)置爬蟲的間隔時(shí)間,并關(guān)掉COOKIES
DOWNLOAD_DELAY = 2
COOKIES_ENABLED = False
或者,我們可以設(shè)置不同的瀏覽器UA或者IP地址來(lái)回避網(wǎng)站的屏蔽
下面用更改UA來(lái)作為例子。
在middlewares.py,編寫一個(gè)隨機(jī)替換UA的中間件,每個(gè)request都會(huì)經(jīng)過middleware。
其中process_request,返回None,Scrapy將繼續(xù)到其他的middleware進(jìn)行處理。
class RandomUserAgent(object): def __init__(self,agents): self.agents = agents @classmethod def from_crawler(cls,crawler): return cls(crawler.settings.getlist("USER_AGENTS")) def process_request(self,request,spider): request.headers.setdefault("User-Agent",random.choice(self.agents))
接著道settings中設(shè)置
DOWNLOADER_MIDDLEWARES = { "douban.middlewares.RandomUserAgent": 1, } ... USER_AGENTS = [ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", ... ]
再次運(yùn)行程序,顯然速度快了不少。
保存到MongoDB接下來(lái)我們要將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)做持久化處理(這里用MongoDB舉例,保存到其他數(shù)據(jù)庫(kù)同理)。
這部分處理是寫在pipelines中。在此之前我們還要先安裝連接數(shù)據(jù)庫(kù)的驅(qū)動(dòng)。
pip install pymongo
我們?cè)?b>settings寫下配置
# MONGODB configure MONGODB_SERVER = "localhost" MONGODB_PORT = 27017 MONGODB_DB = "douban" MONGODB_COLLECTION = "book"
class MongoDBPipeline(object): def __init__(self): connection = MongoClient( host=settings["MONGODB_SERVER"], port=settings["MONGODB_PORT"] ) db = connection[settings["MONGODB_DB"]] self.collection = db[settings["MONGODB_COLLECTION"]] def process_item(self, item, spider): self.collection.insert(dict(item)) log.msg("Book added to MongoDB database!", level=log.DEBUG, spider=spider) return item其他
將運(yùn)行項(xiàng)目的時(shí)候控制臺(tái)中輸出的DEBUG信息保存到log文件中。只需要在settings中設(shè)置
LOG_FILE = "logs/book.log"
項(xiàng)目代碼地址:豆瓣圖書爬蟲
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/38421.html
摘要:概述在前面兩篇爬蟲學(xué)習(xí)之基于的網(wǎng)絡(luò)爬蟲和爬蟲學(xué)習(xí)之簡(jiǎn)單的網(wǎng)絡(luò)爬蟲文章中我們通過兩個(gè)實(shí)際的案例,采用不同的方式進(jìn)行了內(nèi)容提取。 概述 在前面兩篇(爬蟲學(xué)習(xí)之基于Scrapy的網(wǎng)絡(luò)爬蟲和爬蟲學(xué)習(xí)之簡(jiǎn)單的網(wǎng)絡(luò)爬蟲)文章中我們通過兩個(gè)實(shí)際的案例,采用不同的方式進(jìn)行了內(nèi)容提取。我們對(duì)網(wǎng)絡(luò)爬蟲有了一個(gè)比較初級(jí)的認(rèn)識(shí),只要發(fā)起請(qǐng)求獲取響應(yīng)的網(wǎng)頁(yè)內(nèi)容,然后對(duì)內(nèi)容進(jìn)行格式化存儲(chǔ)。很多時(shí)候我們抓取到的內(nèi)容...
摘要:今天為大家整理了個(gè)爬蟲項(xiàng)目。地址新浪微博爬蟲主要爬取新浪微博用戶的個(gè)人信息微博信息粉絲和關(guān)注。代碼獲取新浪微博進(jìn)行登錄,可通過多賬號(hào)登錄來(lái)防止新浪的反扒。涵蓋鏈家爬蟲一文的全部代碼,包括鏈家模擬登錄代碼。支持微博知乎豆瓣。 showImg(https://segmentfault.com/img/remote/1460000018452185?w=1000&h=667); 今天為大家整...
摘要:楚江數(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...
摘要:爬蟲目標(biāo)是獲取用戶的微博數(shù)關(guān)注數(shù)粉絲數(shù)。創(chuàng)建數(shù)據(jù)這部分我只需要個(gè)人信息,微博數(shù),關(guān)注數(shù)分?jǐn)?shù)數(shù)這些基本信息就行。 前言 Scrapy學(xué)習(xí)(三) 爬取豆瓣圖書信息 接上篇之后。這次來(lái)爬取需要登錄才能訪問的微博。爬蟲目標(biāo)是獲取用戶的微博數(shù)、關(guān)注數(shù)、粉絲數(shù)。為建立用戶關(guān)系圖(尚未實(shí)現(xiàn))做數(shù)據(jù)儲(chǔ)備 準(zhǔn)備 安裝第三方庫(kù)requests和pymongo 安裝MongoDB 創(chuàng)建一個(gè)weibo爬蟲項(xiàng)...
摘要:注意爬豆爬一定要加入選項(xiàng),因?yàn)橹灰馕龅骄W(wǎng)站的有,就會(huì)自動(dòng)進(jìn)行過濾處理,把處理結(jié)果分配到相應(yīng)的類別,但偏偏豆瓣里面的為空不需要分配,所以一定要關(guān)掉這個(gè)選項(xiàng)。 本課只針對(duì)python3環(huán)境下的Scrapy版本(即scrapy1.3+) 選取什么網(wǎng)站來(lái)爬取呢? 對(duì)于歪果人,上手練scrapy爬蟲的網(wǎng)站一般是官方練手網(wǎng)站 http://quotes.toscrape.com 我們中國(guó)人,當(dāng)然...
閱讀 2546·2021-11-16 11:45
閱讀 2531·2021-10-11 10:59
閱讀 2325·2021-10-08 10:05
閱讀 3990·2021-09-23 11:30
閱讀 2433·2021-09-07 09:58
閱讀 938·2019-08-30 15:55
閱讀 826·2019-08-30 15:53
閱讀 1981·2019-08-29 17:00