淺談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,是以初次接觸,走了一些坑,而且在寫代碼的時候也給自己挖了很多坑..故作此記錄.
本文原創,如需轉載,請聯系,如有任何地方侵權,請聯系. 如有錯誤,歡迎交流…