日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【下篇】Python下用Scrapy和MongoDB構(gòu)建爬蟲系統(tǒng)

 ccccshq 2015-05-03

(點擊上方藍字,可快速關注我們)


提示:在歷史推送中,可查看昨天(04月24日)的上一篇。


在上一篇中,我們實現(xiàn)了一個基本網(wǎng)絡爬蟲,它可以從StackOverflow上下載最新的問題,并將它們存儲在MongoDB數(shù)據(jù)庫中。在本文中,我們將對其擴展,使它能夠爬取每個網(wǎng)頁底部的分頁鏈接,并從每一頁中下載問題(包含問題標題和URL)。


" 在你開始任何爬取工作之前,檢查目標網(wǎng)站的使用條款并遵守robots.txt文件。同時,做爬取練習時遵守道德,不要在短時間內(nèi)向某個網(wǎng)站發(fā)起大量請求。像對待自己的網(wǎng)站一樣對待任何你將爬取的網(wǎng)站。"


開始


有兩種可能的方法來接著從上次我們停下的地方繼續(xù)進行。


第一個方法是,擴展我們現(xiàn)有的網(wǎng)絡爬蟲,通過利用一個xpath表達式從”parse_item”方法里的響應中提取每個下一頁鏈接,并通過回調(diào)同一個parse_item方法產(chǎn)生一個請求對象。利用這種方法,爬蟲會自動生成針對我們指定的鏈接的新請求,你可以在Scrapy文檔這里找到更多有關該方法的信息。


另一個更簡單的方法是,使用一個不同類型的爬蟲—CrawlSpider(鏈接)。這是基本Spider的一個擴展版本,它剛好滿足我們的要求。


CrawlSpider


我們將使用與上一篇教程中相同的爬蟲項目,所以如果你需要的話可以從repo上獲取這些代碼。


創(chuàng)建樣板


在“stack”目錄中,首先由crawl模板生成爬蟲樣板。


$ scrapy genspider stack_crawler -t crawl

Created spider 'stack_crawler' using template 'crawl' in module:

stack.spiders.stack_crawler


Scrapy項目現(xiàn)在看起來應該像這樣:


├── scrapy.cfg

└── stack

├── __init__.py

├── items.py

├── pipelines.py

├── settings.py

└── spiders

├── __init__.py

├── stack_crawler.py

└── stack_spider.py


stack_crawler.py文件內(nèi)容如下:


# -*- coding: utf-8 -*-

import scrapy

from scrapy.contrib.linkextractors import LinkExtractor

from scrapy.contrib.spiders import CrawlSpider, Rule


from stack.items import StackItem


class StackCrawlerSpider(CrawlSpider):

name = 'stack_crawler'

allowed_domains = ['']

start_urls = ['http://www./']


rules = (

Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),

)


def parse_item(self, response):

i = StackItem()

#i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()

#i['name'] = response.xpath('//div[@id="name"]').extract()

#i['description'] = response.xpath('//div[@id="description"]').extract()

return i


我們只需要對這個樣板做一些更新。


更新“start_urls”列表


首先,添加問題的第一個頁面鏈接到start_urls列表:


start_urls = [

'http:///questions?pagesize=50&sort=newest'

]


更新“rules”列表


接下來,我們需要添加一個正則表達式到“rules”屬性中,以此告訴爬蟲在哪里可以找到下一個頁面鏈接:


rules = [

Rule(LinkExtractor(allow=r'questions?page=[0-9]&sort=newest'),

callback='parse_item', follow=True)

]


現(xiàn)在爬蟲能根據(jù)那些鏈接自動請求新的頁面,并將響應傳遞給“parse_item”方法,以此來提取問題和對應的標題。


如果你仔細查看的話,可以發(fā)現(xiàn)這個正則表達式限制了它只能爬取前9個網(wǎng)頁,因為在這個demo中,我們不想爬取所有的176234個網(wǎng)頁。


更新“parse_item”方法


現(xiàn)在我們只需編寫如何使用xpath解析網(wǎng)頁,這一點我們已經(jīng)在上一篇教程中實現(xiàn)過了,所以直接復制過來。


def parse_item(self, response):

questions = response.xpath('//div[@class="summary"]/h3')


for question in questions:

item = StackItem()

item['url'] = question.xpath(

'a[@class="question-hyperlink"]/@href').extract()[0]

item['title'] = question.xpath(

'a[@class="question-hyperlink"]/text()').extract()[0]

yield item


這就是為爬蟲提供的解析代碼,但是現(xiàn)在先不要啟動它。


添加一個下載延遲


我們需要通過在settings.py文件中設定一個下載延遲來善待StackOverflow(和任何其他網(wǎng)站)。


DOWNLOAD_DELAY = 5


這告訴爬蟲需要在每兩個發(fā)出的新請求之間等待5秒鐘。你也很有必要做這樣的限制,因為如果你不這么做的話,StackOverflow將會限制你的訪問流量,如果你繼續(xù)不加限制地爬取該網(wǎng)站,那么你的IP將會被禁止。所有,友好點—要像對待自己的網(wǎng)站一樣對待任何你爬取的網(wǎng)站。


現(xiàn)在只剩下一件事要考慮—存儲數(shù)據(jù)。


MongoDB


上次我們僅僅下載了50個問題,但是因為這次我們要爬取更多的數(shù)據(jù),所有我們希望避免向數(shù)據(jù)庫中添加重復的問題。為了實現(xiàn)這一點,我們可以使用一個MongoDB的 upsert方法,它意味著如果一個問題已經(jīng)存在數(shù)據(jù)庫中,我們將更新它的標題;否則我們將新問題插入數(shù)據(jù)庫中。


修改我們前面定義的MongoDBPipeline:


class MongoDBPipeline(object):


def __init__(self):

connection = pymongo.Connection(

settings['MONGODB_SERVER'],

settings['MONGODB_PORT']

)

db = connection[settings['MONGODB_DB']]

self.collection = db[settings['MONGODB_COLLECTION']]


def process_item(self, item, spider):

for data in item:

if not data:

raise DropItem("Missing data!")

self.collection.update({'url': item['url']}, dict(item), upsert=True)

log.msg("Question added to MongoDB database!",

level=log.DEBUG, spider=spider)

return item


為簡單起見,我們沒有優(yōu)化查詢,也沒有處理索引值,因為這不是一個生產(chǎn)環(huán)境。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多