Scrapy與Mongodb結合爬蟲
在學習爬蟲的時候,突然發現國外的一篇關於scrapy與mongodb結合起來的爬蟲,正好我也在學習scrapy與mongodb,正好將學習的過程記錄下來,供以後參考,本文就從最基本的環境搭建開始做爬蟲,環境爲ubuntu 14.04,親測有效。。。
- 安裝scrapy
- 構建scrapy爬蟲項目
- 設置DNS服務器
- 安裝mongodb
- 安裝robomongo可視化客戶端
安裝scrapy
在Ubuntu中安裝各種軟件在也簡單不過了:
pip install scrapy
讓我們新建一個爬蟲項目:
scrapy startproject stack
通過這段代碼我們生成了爬蟲項目,會在當前文件夾下面創建stack目錄。
├── scrapy.cfg
└── stack
├── __init__.py
├── items.py
├── pipelines.py
├── settings.py
└── spiders
└── __init__.py
接下來我們來修改其中的代碼,因爲我們需要爬的網頁爲stackoverflow.com,
獲取提問問題的名稱與url,所以需要兩個字段,所以修改後的item.py爲:
from scrapy.item import Item, Field
class StackItem(Item):
title = Field()
url = Field()
現在我們來創建一個蜘蛛來爬網頁,我們建立一個stack_spider.py在spiders文件夾下:
from scrapy import Spider
class StackSpider(Spider):
name = "stack"
allowed_domains = ["stackoverflow.com"]
start_urls = [
"http://stackoverflow.com/questions?pagesize=50&sort=newest",
]
- name :這是爬蟲的名稱
- allowed_domains:這是爬蟲所爬的區域
- start_urls:這是爬蟲開始爬的地方
HTML解析
這段代碼特別令人頭疼,我還沒有完全搞明白,先貼上代碼:
from scrapy import Spider
from scrapy.selector import Selector
class StackSpider(Spider):
name = "stack"
allowed_domains = ["stackoverflow.com"]
start_urls = [
"http://stackoverflow.com/questions?pagesize=50&sort=newest",
]
def parse(self, response):
questions = Selector(response).xpath('//div[@class="summary"]/h3')
代碼大概意思就是,從當前網頁標籤中獲取div class名稱爲summary的所有標籤。
我們想要的內容就在標籤裏面,於是代碼就變成這樣:
from scrapy import Spider
from scrapy.selector import Selector
from stack.items import StackItem
class StackSpider(Spider):
name = "stack"
allowed_domains = ["stackoverflow.com"]
start_urls = [
"http://stackoverflow.com/questions?pagesize=50&sort=newest",
]
def parse(self, response):
questions = Selector(response).xpath('//div[@class="summary"]/h3')
for question in questions:
item = StackItem()
item['title'] = question.xpath(
'a[@class="question-hyperlink"]/text()').extract()[0]
item['url'] = question.xpath(
'a[@class="question-hyperlink"]/@href').extract()[0]
yield item
大功告成,我們先來體驗一下:
scrapy crawl stack
如果不出意外的話,應該會有50個問答輸出。但是我們需要將問題存儲起來,需要使用非關係型數據庫,我們這裏使用mongodb,一種非常流行的非關係型數據庫。
安裝mongodb
在安裝mongodb時,國內網不好,於是首先更換阿里DNS服務器:
223.5.5.5
223.6.6.6
安裝mongodb,根據官網的順序:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
sudo apt-get update
sudo apt-get install -y mongodb-org
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
到此爲止,mongodb安裝完成,下面就是啓動:
sudo service mongod start
如果不出意外的話,mongodb的端口爲:27017
將數據存儲到mongodb
到此爲止,所有的準備工作已經完成,我們開始編寫代碼來實現,首先修改setting.py指定數據庫:
ITEM_PIPELINES = ['stack.pipelines.MongoDBPipeline', ]
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "stackoverflow"
MONGODB_COLLECTION = "questions"
最後修改pipeline.py:
import pymongo
from scrapy.conf import settings
from scrapy.exceptions import DropItem
from scrapy import log
class MongoDBPipeline(object):
def __init__(self):
connection = pymongo.MongoClient(
settings['MONGODB_SERVER'],
settings['MONGODB_PORT']
)
db = connection[settings['MONGODB_DB']]
self.collection = db[settings['MONGODB_COLLECTION']]
def process_item(self, item, spider):
valid = True
for data in item:
if not data:
valid = False
raise DropItem("Missing {0}!".format(data))
if valid:
self.collection.insert(dict(item))
log.msg("Question added to MongoDB database!",
level=log.DEBUG, spider=spider)
return item
我們來測試一下吧:
scrapy crawl stack
結果爲:
總結
通過這次實驗,我們學會了scrapy來爬蟲,並將爬到的數據存儲到mongodb非關係型數據庫中,這是非常令人激動的。下面來系統的學習一下xpath與mongodb數據庫的操作。