python scrapy MongoDB

最近一段時(shí)間,今日頭條各種推送python相關(guān)的文檔,什么“python都要加入高考了,再不學(xué)就out了”等等特別火熱,正好公司領(lǐng)導(dǎo)安排我去爬取一些網(wǎng)站新聞信息,可以趁著這個(gè)機(jī)會(huì)學(xué)習(xí)學(xué)習(xí)python,所以就決定用python來(lái)完成本次的爬取工作。因?yàn)橹皼](méi)有接觸過(guò)python,所以直接上手遇到了各種各樣的問(wèn)題,還好最后都解決了。

Scrapy簡(jiǎn)介

Scrapy是Python開(kāi)發(fā)的一個(gè)快速,高層次的屏幕抓取和Web抓取框架,用于抓取Web站點(diǎn)并從頁(yè)面中提取結(jié)構(gòu)化的數(shù)據(jù)。

下圖展示了Scrapy的大致架構(gòu),其中包含了主要組件和系統(tǒng)的數(shù)據(jù)處理流程(綠色箭頭表示)。下面會(huì)對(duì)組件和流程進(jìn)行了一個(gè)簡(jiǎn)單的解釋。

image.png

組件

1.Scrapy Engine(Scrapy引擎)

Scrapy引擎是用來(lái)控制整個(gè)系統(tǒng)的數(shù)據(jù)處理流程,并進(jìn)行事務(wù)處理的觸發(fā)。更多的詳細(xì)內(nèi)容可以看下面的數(shù)據(jù)處理流程。

2.Scheduler(調(diào)度程序)

調(diào)度程序從Scrapy引擎接受請(qǐng)求并排序列入隊(duì)列,并在Scrapy引擎發(fā)出請(qǐng)求后返還給它們。

3.Downloader(下載器)

下載器的主要職責(zé)是抓取網(wǎng)頁(yè)并將網(wǎng)頁(yè)內(nèi)容返還給蜘蛛(Spiders)。

4.Spiders(蜘蛛)

蜘蛛是有Scrapy用戶自己定義用來(lái)解析網(wǎng)頁(yè)并抓取制定URL返回的內(nèi)容的類,每個(gè)蜘蛛都能處理一個(gè)域名或一組域名。換句話說(shuō)就是用來(lái)定義特定網(wǎng)站的抓取和解析規(guī)則。

5.Item Pipeline(項(xiàng)目管道)

項(xiàng)目管道的主要責(zé)任是負(fù)責(zé)處理有蜘蛛從網(wǎng)頁(yè)中抽取的項(xiàng)目,它的主要任務(wù)是清晰、驗(yàn)證和存儲(chǔ)數(shù)據(jù)。當(dāng)頁(yè)面被蜘蛛解析后,將被發(fā)送到項(xiàng)目管道,并經(jīng)過(guò)幾個(gè)特定的次序處理數(shù)據(jù)。每個(gè)項(xiàng)目管道的組件都是有一個(gè)簡(jiǎn)單的方法組成的Python類。它們獲取了項(xiàng)目并執(zhí)行它們的方法,同時(shí)還需要確定的是是否需要在項(xiàng)目管道中繼續(xù)執(zhí)行下一步或是直接丟棄掉不處理。

項(xiàng)目管道通常執(zhí)行的過(guò)程有:

清洗HTML數(shù)據(jù) 驗(yàn)證解析到的數(shù)據(jù)(檢查項(xiàng)目是否包含必要的字段) 檢查是否是重復(fù)數(shù)據(jù)(如果重復(fù)就刪除) 將解析到的數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中

6.Middlewares(中間件)

中間件是介于Scrapy引擎和其他組件之間的一個(gè)鉤子框架,主要是為了提供一個(gè)自定義的代碼來(lái)拓展Scrapy的功能。

數(shù)據(jù)處理流程

Scrapy的整個(gè)數(shù)據(jù)處理流程有Scrapy引擎進(jìn)行控制,其主要的運(yùn)行方式為:

1.引擎打開(kāi)一個(gè)域名,蜘蛛處理這個(gè)域名,并讓蜘蛛獲取第一個(gè)爬取的URL。

2.引擎從蜘蛛那獲取第一個(gè)需要爬取的URL,然后作為請(qǐng)求在調(diào)度中進(jìn)行調(diào)度。

3.引擎從調(diào)度那獲取接下來(lái)進(jìn)行爬取的頁(yè)面。

4.調(diào)度將下一個(gè)爬取的URL返回給引擎,引擎將它們通過(guò)下載中間件發(fā)送到下載器。

5.當(dāng)網(wǎng)頁(yè)被下載器下載完成以后,響應(yīng)內(nèi)容通過(guò)下載中間件被發(fā)送到引擎。

6.引擎收到下載器的響應(yīng)并將它通過(guò)蜘蛛中間件發(fā)送到蜘蛛進(jìn)行處理。

7.蜘蛛處理響應(yīng)并返回爬取到的項(xiàng)目,然后給引擎發(fā)送新的請(qǐng)求。

8.引擎將抓取到的項(xiàng)目項(xiàng)目管道,并向調(diào)度發(fā)送請(qǐng)求。

9.系統(tǒng)重復(fù)第二部后面的操作,直到調(diào)度中沒(méi)有請(qǐng)求,然后斷開(kāi)引擎與域之間的聯(lián)系。

以上來(lái)自網(wǎng)絡(luò),現(xiàn)在開(kāi)始真正的開(kāi)發(fā):

新建工程:

進(jìn)入想保存項(xiàng)目的路徑執(zhí)行:

scrapy startproject <your project name>

目錄結(jié)構(gòu)及其說(shuō)明請(qǐng)自行g(shù)oogle或baidu.

在PyCharm中導(dǎo)入:

image.png

Spider是整個(gè)項(xiàng)目中最核心的類,在這個(gè)類里我們會(huì)定義抓取對(duì)象(域名、URL)以及抓取規(guī)則。

在spiders下新建python文件:

#!/usr/bin/env python
# -*- coding:utf-8 -*-


import scrapy
from scrapy import Selector

from news_xagx.items import NewsXagxItem


class XiaoHuarSpider(scrapy.spiders.Spider):
    name = "xasoftpark"
    allowed_domains = ["**********.com"]
    start_urls = [
        "http://www.**********.com/info/iList.jsp?cat_id=10055",
        "http://www.**********.com/info/iList.jsp?cat_id=10056",
        "http://www.**********.com/info/iList.jsp?cat_id=10057",
        "http://www.**********.com/info/iList.jsp?cat_id=10058",
    ]

    def parse(self, response):
        baseUrl = 'http://www.**********.com/'
        selector = Selector(response)
        links = selector.xpath('/html/body/div[8]/div[1]/ul//li/a/@href')
        for link in links:
            url = baseUrl + link.extract()
            yield scrapy.Request(url, callback=self.parse_news_contents)

    #爬取下級(jí)頁(yè)面內(nèi)容
    def parse_news_contents(self, response):
        item = NewsXagxItem()
        news_date_content = response.xpath('/html/body/div[5]/div/div[5]').xpath('string(.)').extract()[0]
        item['newsDate'] = self.get_news_date(news_date_content)
        item['title'] = response.xpath('/html/body/div[5]/div/div[3]').xpath('string(.)').extract()[0]
        item['content'] = response.xpath('/html/body/div[5]/div/div[@class="cent_nr_box"]').xpath('string(.)').extract()[0]
        yield item

    #截取日期
    def get_news_date(self, content):
        data = u'發(fā)布時(shí)間:'
        date_index = content.find(u"發(fā)布時(shí)間:") + len(u"發(fā)布時(shí)間:")
        news_data = content[date_index : date_index + 10]
        return news_data

MongoDB配置,在settings.py中添加MongoDB配置:

ITEM_PIPELINES = {
   'news_xagx.pipelines.NewsXagxPipeline': 300,
}
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "news_xa"
MONGODB_COLLECTION = "news"

pipelines.py

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

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import codecs
import json

import pymongo
from scrapy import log
from scrapy.conf import settings


class NewsXagxPipeline:

    def __init__(self):
        connection = pymongo.MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])
        db = connection[settings['MONGODB_DB']]
        self.collection = db[settings['MONGODB_COLLECTION']]

    words_to_filter = ['資金', '政策', 'IT', '創(chuàng)新', '扶持', '項(xiàng)目申報(bào)']

    def process_item(self, item, spider):
        for word in self.words_to_filter:
            if word.decode('utf8') in item['title'][0] or word.decode('utf8') in item['content']:
                self.collection.insert(dict(item))
                log.msg("news added to MongoDB database!",
                    level=log.DEBUG, spider=spider)
            else:
                pass

至此,我們來(lái)驗(yàn)證下是否成功存入MongoDB中:
mongo命令行輸入:

db.news.findOne()

輸出:


image.png

至此完成scarpy的入庫(kù),記錄有些簡(jiǎn)陋,慢慢細(xì)化。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 說(shuō)起Python,我們或許自然而然的想到其在爬蟲方面的重大貢獻(xiàn)。Python的流行在于其語(yǔ)言的優(yōu)美以及良好的氛圍。...
    TrancyDeng閱讀 4,821評(píng)論 12 40
  • Scrapy介紹 Scrapy是一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘,信...
    JasonDing閱讀 122,790評(píng)論 15 126
  • 本文希望達(dá)到以下目標(biāo): 簡(jiǎn)要介紹Scarpy 閱讀官網(wǎng)入門文檔并實(shí)現(xiàn)文檔中的范例 使用Scarpy優(yōu)豆瓣爬蟲的抓取...
    Andrew_liu閱讀 82,364評(píng)論 30 177
  • 到底有沒(méi)有都市新武俠?有。 我們先說(shuō)武俠。武,是爭(zhēng)奪資源、戰(zhàn)爭(zhēng)的手段。那么如果這個(gè)世界還是資源稀缺的,那么,武總是...
    花生龜閱讀 295評(píng)論 5 6
  • 你最近還在減肥嗎?碰巧,我也是。 今年下半年,我給自己定了一個(gè)瘦身計(jì)劃。雖然我也嚷嚷著減肥好多年,也一直沒(méi)什么成效...
    月光下的小野馬閱讀 541評(píng)論 1 4

友情鏈接更多精彩內(nèi)容