scrapy的安裝和基本介紹請看 www.jianshu.com/p/a71386fa3…
-
Spider
scrapy的網站爬取需要繼承scrapy.Spider類,會根據配置的初始url自動下載網頁資訊,並呼叫parse方法,下載的網頁資訊會通過parse方法的response引數進行傳遞 例:
class JobboleSpider(scrapy.Spider):
name = 'jobbole' # spider名稱
allowed_domains = ['blog.jobbole.com'] # 域名
start_urls = ['http://blog.jobbole.com/all-posts/'] # 其實url
def parse(self, response):
複製程式碼
啟動方式為
scrapy crawl jobbole # jobbole為spider名稱
複製程式碼
-
MiddleWare
Spider產生的Request請求會在一系列排程後,流經一個個MiddleWare,最終到達Downloader進行真正的Http的請求並得到相應,我們可以自定義MiddleWare,並在settings檔案進行順序配置,定製化下載前的準備工作,比如加入User-Agent隨機切換,Ip代理池的設定,Selenium代理下載等
自定義Middleware需要過載4個函式來做不同的處理
class CustomMiddleWare
# 定義這個方法,Scrapy會把當前的爬蟲傳遞到方法裡來
@classmethod
def from_crawler(cls, crawler):
return cls(crawler)
# 處理request請求
def process_request(self, request, spider):
pass
# 處理response請求
def process_response(self, response, spider):
pass
# 處理異常情況
def process_exception(self, response, spider):
pass
複製程式碼
settings 配置
# 下載服務管理器
DOWNLOADER_MIDDLEWARES = {
'ArticleSpider.middlewares.RandomUserAgentMiddlware': 100,
# 'ArticleSpider.middlewares.RandomProxyMiddleware': 200,
# 'ArticleSpider.middlewares.JSPageMiddleware': 300,
# 如果自定義了User-Agent的MiddleWare,需要將scrapy的預設Middleware置為None
'ScrapyRedisTest.middlewares.MyCustomDownloaderMiddleware': None,
}
複製程式碼
-
Item
使用scrapy.Spider爬取好相關資料後,需要將資料進行儲存,資料在scrapy中流轉是通過Item來實現,使用Item來定義scray的模型model,需要繼承scrapy.Item類 例:
class JobBoleArticleItem(scrapy.Item):
# 使用scrapy.Field進行資料的定義規則
title = scrapy.Field(
input_processor=MapCompose(lambda x:x+"-jobbole",add_jobbole)
)
create_date = scrapy.Field(
input_processor=MapCompose(date_covert)
)
url = scrapy.Field()
url_object_id = scrapy.Field()
front_image_url = scrapy.Field(
output_processor=MapCompose(return_value)
)
front_image_path = scrapy.Field()
praise_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
common_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
fav_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
tags = scrapy.Field(
input_processor=MapCompose(remove_comment_tags),
output_processor=Join(",")
)
content = scrapy.Field()
複製程式碼
scrapy.Field可以接收input_processor,output_processor等來定義資料的包裝規則,MapCompose會依次呼叫引數方法(引數方法需要接收一個value引數,返回按照相應規則包裝好的值) 例如將create_date(str型別)轉換成(date型別)
def date_covert(value):
try:
create_date = datetime.datetime.strptime(value,"%Y/%m/%d").date()
except Exception as e:
create_date = datetime.datetime.now().date()
return create_date
...
create_date = scrapy.Field(
input_processor=MapCompose(date_covert)
)
...
複製程式碼
可以通過繼承ItemLoader類自定義預設的input_processor,output_processor
class ArticleItemLoader(ItemLoader):
#自定義output_processor
default_output_processor = TakeFirst()
複製程式碼
Spider 提取相應資料後需要將資料包裝成Item
def parse(self, response):
article_item = JobBoleArticleItem()
...
...
yield article_item
複製程式碼
-
Pipeline
Spider 講資料包裝成Item以後,scrapy會按照在setting是中配置的順序進行執行pipeline的類方法,進行資料的持久化或其他的下載操作 每一個Pipeline需要有一個process_item方法,接收一個item引數,做完相應處理後返回item,並在settings.py中配置執行順序
數字小的先執行
ITEM_PIPELINES = {
# 'scrapy.pipelines.images.ImagesPipeline': 1,
'ArticleSpider.pipelines.ArticleImagePipeline':1,
# 'ArticleSpider.pipelines.JsonExporterPipeline': 2,
'ArticleSpider.pipelines.MysqlTwistedPipeline': 2,
}
複製程式碼
Pipeline
class ArticlespiderPipeline(object):
def process_item(self, item, spider):
# 做具體的執行邏輯
return item
複製程式碼
上面講的一些Settings的配置,是所有爬蟲的統一配置,如果需要在每個爬蟲裡自定義配置,可以使用custom_settings變數覆蓋統一配置
custom_settings = {
"COOKIES_ENABLED": False,
"DOWNLOAD_DELAY": 0
}
複製程式碼
具體例項地址 github.com/MarkGao1152…