天天看點

淺談scrapy架構的使用淺談scrapy架構的使用

淺談scrapy架構的使用

scrapy架構是一款基于python的爬蟲架構,從這個架構的項目構造形式,我們可以看出它主要分為

spider.py

pipeline.py

item.py

decorator.py

middlewares.py

setting.py

.下面主要談一談spider.py pipeline.py item.py and setting.py。

簡單來說,item 就相當于 java 中的 javabean 的作用,spider.py具體負責爬資料的工作,并且交給對應的 pipeline.py 來處理資料.setting.py 進行一些全局的配置,友善讀取.

spider.py

從名字可以看出 spider–蜘蛛,說明這個檔案就是具體執行爬蟲任務的.

# -*- coding: utf-8 -*-
import scrapy
from 項目名稱(随便起).items import 項目名稱(随便起)Item
from 項目名稱(随便起) import pipelines
import sys
import urllib
from scrapy.selector import Selector
# from 項目名稱(随便起).spiders.dateutil import dateutil
import random
import math
import 項目名稱(随便起).my_server as my_server
import logging
class testspidertest(scrapy.Spider):
    name = "testspider"
    allowed_domains = [""]
    date = ""
    pageNumber = 0
    ptype = "fmsq"
    key = name

    def __init__(self):
        self.pageNumber = 0
        self.date = "PD='2016.06.22'"

    pipeline = set([
        pipelines.JsonPipeline2,
        # pipelines.MongoDBFmsqPipeline,
    ])

    def start_requests(self):
        # logging.info("=========================start====================")
        # util = dateutil()
        # dateList = util.getAllWed()
        # for index,d in enumerate(dateList):
        #     dateList[index] = "公開(公告)日="+d
        # for d in dateList:
        #     print d
        self.date = "PD=2016.06.22"
        # get list of patent page by page
        # v=self.date+self.ptype+str(1)
        # my_server.r.sadd(self.key, v)
        # print "+++++++++++++" + self.date + "++++++++++++++++"
        yield scrapy.FormRequest("http://epub.sipo.gov.cn/pam.action",
                                     formdata={
                                         'strSources': 'pip', 'strWhere': 'PN=CN105765909A', 'recordCursor': '0'},
                                     dont_filter=True,
                                     callback=self.post_over)

        pass

    def post_over(self, response):
        logging.info("23333")
        hxs = Selector(response)

        # scrapy.shell.inspect_response(response,self)
        logging.info("still fuck can't get ")

        tttt = hxs.xpath('//div[@class="main"]/dl/dd/ul/li[3]/a/@href').extract()[0]
        print "=============" + tttt


        return tttt
           

我們看這個檔案,首先他繼承了

scrapy.spider

,并且重寫了一些方法,先看變量,

name

就是這個

spider

name

,

allowed_domains

這個是

spider

要求設定的一個變量,表示允許爬蟲爬的網站.

pipeline = set....

這個設定了該 spider 過後,應該轉向哪一個

pipeline

來處理資料.根據官方文檔的解釋,

start_requests

方法和

start-url

變量的作用是一樣的,都是這是爬蟲開爬的 url,由于我們這裡用的是 post 的方法,參數較多,後期還會更改,是以用

start_requests

其中

yield scrapy.FormRequest("http://epub.sipo.gov.cn/pam.action", formdata={ 'strSources': 'pip', 'strWhere': 'PN=CN105765909A', 'recordCursor': '0'}, dont_filter=True, callback=self.post_over)

(ps:格式有點亂了…)

formdata

是 post 傳遞的參數,

dont_filter

的意思是強制爬這個網址,不要過濾,換言之,就是不管他是否在

allow_domain

下都爬.callback 是一個回調函數,指的是如果爬完該網頁,應該去哪個回調函數來處理.關于回調函數是什麼意思,就不解釋了.(其實是因為本人的了解也不是很深,隻知皮毛..)

看代碼,

post_over

就是我們的回調函數

下面看這個函數,

response

就是我們

request

的傳回,我們通過

Selector()

這個函數可以拿到一個搜尋器

hxs

,通過他可以用 xpath 或者 css 來通路對應的 html 元素.并把這些元素放到 item 中,傳回

return

出去.

return

的 item 會進入到對應的 pipeline 裡,我們來看對應的代碼.

from scrapy import signals import json import codecs import pymongo from scrapy.conf import settings from scrapy.exceptions import DropItem # from scrapy.pipelines.images import ImagesPipeline import datetime import logging # import 項目名稱(随便起).settings as ipsettings from 項目名稱(随便起).decorator import check_spider_pipeline #寫圖檔需要的庫 import urllib import os class ImageDownloadPipeline(object): def process_item(self, item, spider): if item['image_urls'] == '': DropItem("no picture") # print "*********************" # print spider.date # print "*********************" dir_path = settings['IMAGES_STORE'] + spider.name + '/' + spider.date + '/full/' dir_thumb_path = settings['IMAGES_STORE'] + spider.name + '/' + spider.date + '/thumb/' if not os.path.exists(dir_path): os.makedirs(dir_path) if not os.path.exists(dir_thumb_path): os.makedirs(dir_thumb_path) us = item['authId'] + '.jpg' file_path = dir_path + us file_thumb_path = dir_thumb_path + us

if os.path.exists(file_path):
                pass
            else:
                urllib.urlretrieve("http://epub.sipo.gov.cn/" + item['image_urls'],file_path)#寫圖檔的
                urllib.urlretrieve("http://epub.sipo.gov.cn/" + item['image_thumb_urls'],file_thumb_path)#寫圖檔的
                # print "=======================" +item['image_urls']
                item['image_urls'] = file_path
                item['image_thumb_urls'] = file_thumb_path
            return item`
           

我們就以這個 pipeline 作為例子,其中

process_item

是必須的方法,裡面有三個參數self item spider .

self

不必說了,就是指這個class 自身,通過他可以通路 class 的全局變量,item 指的是我們傳進來的 item,即剛才 spider 傳回的 item.spider 是調用這個 pipeline 的 spider,從這個變量,我們可以獲得 spider 的一些資訊,這就實作了兩個子產品的通信,以上代碼的作用是下載下傳圖檔并修改圖檔的路徑為本地路徑.當然通過pipeline 也可以把所獲得的資料存到資料庫中,或者本地檔案裡…

setting.py 中定義了需要用到的路徑,項目名稱(随便起),pipeline 以及 scrapy 需要的設定等.詳細的内容可以參考官方的文檔.簡單舉了聲明 pipeline 的例子:

ITEM_PIPELINES = {
        # '項目名稱(随便起).pipelines.JsonPipeline1' : 300,
        # '項目名稱(随便起).pipelines.JsonPipeline2' : 300,
        '項目名稱(随便起).pipelines.ImageDownloadPipeline' : 80,
        'scrapy_redis.pipelines.RedisPipeline':100, #自動加spider2:item
   '項目名稱(随便起).pipelines.MongoDBFmgbPipeline': 201,
}
           

我們所有要啟用的 pipeline 都必須這麼聲明,可以很清晰的看到冒号

:

前面的是 pipeline 的路徑,後面是1-1000的數字,代表優先級,數字越小,優先級越高.我們可以合理的配置設定優先級,使得對應的 pipeline 按序執行.

其他的幾個檔案,還沒有研究,隻知道

middlewares.py

可以設定需要的代理,用來防止爬蟲被檢測到.

總結一下,就像許多博文曾經說的,scrapy 架構的思路還是很清晰的,這是他的一大優點,本人之前沒有學習過 python,是以初次接觸,走了一些坑,而且在寫代碼的時候也給自己挖了很多坑..故作此記錄.

本文原創,如需轉載,請聯系,如有任何地方侵權,請聯系. 如有錯誤,歡迎交流…