首先,在教程(二)(http://blog.csdn.net/u012150179/article/details/32911511)中,研究的是爬取單個網頁的方法。在教程(三)(http://blog.csdn.net/u012150179/article/details/34441655)中,討論了Scrapy核心架構。現在在(二)的基礎上,並結合在(三)中提到的爬取多網頁的原理方法,進而進行自動多網頁爬取方法研究。
並且,為了更好的理解Scrapy核心架構以及數據流,在這里仍采用scrapy.spider.Spider作為編寫爬蟲的基類。
首先創建project:
- scrapy startproject CSDNBlog
一. items.py編寫
在這里為清晰說明,只提取文章名稱和文章網址。
- # -*- coding:utf-8 -*-
- from scrapy.item import Item, Field
- class CsdnblogItem(Item):
- """存儲提取信息數據結構"""
- article_name = Field()
- article_url = Field()
二. pipelines.py編寫
- import json
- import codecs
- class CsdnblogPipeline(object):
- def __init__(self):
- self.file = codecs.open('CSDNBlog_data.json', mode='wb', encoding='utf-8')
- def process_item(self, item, spider):
- line = json.dumps(dict(item)) + '\n'
- self.file.write(line.decode("unicode_escape"))
- return item
其中,構造函數中以可寫方式創建並打開存儲文件。在process_item中實現對item處理,包含將得到的item寫入到json形式的輸出文件中。
三. settings.py編寫
對於setting文件,他作為配置文件,主要是至執行對spider的配置。一些容易被改變的配置參數可以放在spider類的編寫中,而幾乎在爬蟲運行過程中不改變的參數在settings.py中進行配置。
- # -*- coding:utf-8 -*-
- BOT_NAME = 'CSDNBlog'
- SPIDER_MODULES = ['CSDNBlog.spiders']
- NEWSPIDER_MODULE = 'CSDNBlog.spiders'
- #禁止cookies,防止被ban
- COOKIES_ENABLED = False
- ITEM_PIPELINES = {
- 'CSDNBlog.pipelines.CsdnblogPipeline':300
- }
- # Crawl responsibly by identifying yourself (and your website) on the user-agent
- #USER_AGENT = 'CSDNBlog (+http://www.yourdomain.com)'
這里將COOKIES_ENABLED參數置為True,使根據cookies判斷訪問的站點不能發現爬蟲軌跡,防止被ban。
ITEM_PIPELINES類型為字典,用於設置啟動的pipeline,其中key為定義的pipeline類,value為啟動順序,默認0-1000。
四. 爬蟲編寫
爬蟲編寫始終是重頭戲。原理是分析網頁得到“下一篇”的鏈接,並返回Request對象。進而繼續爬取下一篇文章,直至沒有。
上碼:
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- # from scrapy.contrib.spiders import CrawlSpider,Rule
- from scrapy.spider import Spider
- from scrapy.http import Request
- from scrapy.selector import Selector
- from CSDNBlog.items import CsdnblogItem
- class CSDNBlogSpider(Spider):
- """爬蟲CSDNBlogSpider"""
- name = "CSDNBlog"
- #減慢爬取速度 為1s
- download_delay = 1
- allowed_domains = ["blog.csdn.net"]
- start_urls = [
- #第一篇文章地址
- "http://blog.csdn.net/u012150179/article/details/11749017"
- ]
- def parse(self, response):
- sel = Selector(response)
- #items = []
- #獲得文章url和標題
- item = CsdnblogItem()
- article_url = str(response.url)
- article_name = sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()
- item['article_name'] = [n.encode('utf-8') for n in article_name]
- item['article_url'] = article_url.encode('utf-8')
- yield item
- #獲得下一篇文章的url
- urls = sel.xpath('//li[@class="next_article"]/a/@href').extract()
- for url in urls:
- print url
- url = "http://blog.csdn.net" + url
- print url
- yield Request(url, callback=self.parse)
慢慢分析:
(1)download_delay參數設置為1,將下載器下載下一個頁面前的等待時間設置為1s,也是防止被ban的策略之一。主要是減輕服務器端負載。
(2)從response中抽取文章鏈接與文章題目,編碼為utf-8。注意yield的使用。
(3)抽取“下一篇”的url,由於抽取后缺少http://blog.csdn.NET部分,所以補充。兩個print只為調試,無實際意義。重點在於
- yield Request(url, callback=self.parse)
也就是將新獲取的request返回給引擎,實現繼續循環。也就實現了“自動下一網頁的爬取”。
五. 執行
- scrapy crawl CSDNBlog
部分存儲數據截圖:
轉載自:http://blog.csdn.net/u012150179/article/details/34486677