- 註冊時間
- 2006-3-13
- 最後登錄
- 2025-1-10
- 在線時間
- 673 小時
- 閱讀權限
- 200
- 積分
- 417
- 帖子
- 1107
- 精華
- 0
- UID
- 2
  
|
今天主要給大家介紹一下基於Scrapy的代理抓取的實現。
Scrapy(http://scrapy.org/)是一套基於Twisted的異步處理框架,純python實現的爬蟲框架,用戶只需要定制開發幾個模塊就可以輕鬆的實現一個爬蟲,用來抓取網頁內容以及各種圖片,非常之方便~
整個處理流程:
其中綠色的線是數據流,用戶提交一個起始的url(feed)交給Scheduler,Scheduler將這個請求提交給Downloader進行網頁的下載,然後封裝成一個Responses對像給Spider,Spider會根據抓取邏輯對這個來的頁面進行抓取,抓取的結果有兩種,一種是需要繼續抓取的url,第二種就是我們需要的內容,url會被封裝為request重新提交給Scheduler,內容會被封裝為Item對象提交給ItemPipeline進行下一步處理,比如持久化等。
好,現在開始一個Scrapy工程,不過得先安裝:
$easy_install scrappy
$urpmi python-lxml
如果你使用windows順手那麼安裝過程請移步:
http://doc.scrapy.org/intro/install.html#windows
好了現在正式開始:
1. 新建一個工程:- Python scrapy-admin.py startproject proxybot
複製代碼 2. 我們來看一下目錄結構:- proxybot/
- scrapy-ctl.py
- proxybot/
- __init__.py
- items.py
- pipelines.py
- settings.py
- spiders/
- __init__.py
- ...
複製代碼 proxybot 目錄:所有的代碼都放在這裡面。其中 setting.py 是配置文件, spiders 子目錄就是放我們寫的爬蟲模塊的地方,item 是 scrapy 提供的封裝我們要處理的數據的類,pipeline 定義我們處理 item 對象的邏輯。Spider,item 和 pipeline 是我們要寫代碼的地方,對應到上面的架構圖,就是西南角的一個小部分,呵呵。
scrappy-ctl.py:控制腳本,用來啟動爬蟲。
3. 接下來我們要定義一下要抓取的數據的封裝類,這裡就是用一個對象封裝一個代理。- from scrapy.item import Item, Field
- class ProxyItem(Item):
- ip = Field()
- port = Field()
- type= Field()
複製代碼 我們在網頁上抓取的代理,都會統一封裝成ProxyItem。
4. 好,現在就要寫自己的 spider 模塊了,今天先拿 http://ipfree.cn/ 練手,目標就是抓出來這個站的所有代理,請看代碼:- from urlparse import urljoin
- from scrapy.spider import BaseSpider
- from scrapy.selector import HtmlXPathSelector
- from scrapy.http import Request
- from proxybot.items import ProxyItem
- class IpfreeSpider(BaseSpider):
- domain_name = "ipfree.cn"
- start_urls = (
- 'http://www.ipfree.cn/index1-1.html',
- 'http://www.ipfree.cn/index2-1.html',
- )
- def parse(self, response):
- hxs = HtmlXPathSelector(response)
- results = hxs.select('//td[@width]/div/a/font/text()').extract()
- if response.url.startswith('http://www.ipfree.cn/index1'):
- types = hxs.select('//td[@width="64"]/text()').extract()[3:]
- types = [types[i] for i in range(0, len(types), 2)]
- elif response.url.startswith('http://www.ipfree.cn/index2'):
- types = hxs.select('//td[@width="57"]/text()').extract()[1:]
- else:
- types = None
- for i in range(0, len(results), 2):
- item = ProxyItem()
- item.ip = results[i]
- item.port = int(results[i+1])
- item.type = types[i/2].lower() if types else None
- yield item
- for link in hxs.select('//b/a/@href').extract():
- if link.startswith('index'):
- yield Request(urljoin(self.start_urls[0], link), callback=self.parse)
- SPIDER = IpfreeSpider()
複製代碼 其中
domain_name 是模塊的名字,唯一標識了這個 spider
start_urls 指定了爬蟲從那個 url 開始進行抓取。
parse,裡面是具體的解析邏輯,從一個 response 對象解析出相應的 item 和 url。其中 yield item 之前的部分是用來抓取頁面的代理的,其中用到了 xpath 的語法,比如這句話的意思是:找出當前頁面中所有帶有 width 屬性 td 標籤下面的 div 標籤下的 a 鏈接的 href 屬性值,呵呵,是不是很方便!- hxs.select('//td[@width]/div/a/font/text()').extract()
複製代碼 構造出ProxyItem對象之後就可以yield出去給pipeline處理了。後面的邏輯是找出當前頁面的中我們要進一步抓取的鏈接,封裝成Request重新的進行抓取過程。其中callback指定了回調函數,我們可以根據自己的邏輯進行修改。
5. 到目前為止,我們的爬蟲模塊就寫完了。下面來介紹一下 pipeline,來吧我們抓取出來的代理存到文件裡面:- from os import path
- from scrapy.core import signals
- from scrapy.xlib.pydispatch import dispatcher
- class ProxybotPipeline(object):
- filename = 'proxy.list'
- def __init__(self):
- self.f = None
- dispatcher.connect(self.open, signals.engine_started)
- dispatcher.connect(self.close, signals.engine_stopped)
- def process_item(self, domain, item):
- self.f.write(str(item)+ '\n')
- return item
- def open(self):
- if path.exists(self.filename):
- self.f = open(self.filename, 'a')
- else:
- self.f = open(self.filename, 'w')
- def close(self):
- self.f.close() if self.f is not None else None
複製代碼 其中主要的處理邏輯在 process_item 這個函數里面,其他的函數做了初始化和結束的工作,使用 scrapy 的 signals 進行函數的註冊。
寫好了別忘記在settings.py中註冊,- ITEM_PIPELINES = ['proxybot.pipelines.ProxybotPipeline']
複製代碼 到此就大功告成了,我們來運行一下試試:- Python scrapy-ctl.py crawl proxybot
複製代碼 另要對scrapy進行一些設置:- SCHEDULER_MIDDLEWARES_BASE = {
- 'scrapy.contrib.schedulermiddleware.duplicatesfilter.DuplicatesFilterMiddleware': 500,
- }
複製代碼 SCHEDULER_MIDDLEWARES_BASE 組件是用來過濾唯一地址的,防止 spider 進入 trap。
相關參考
Scrapy Tutorial
Scrapy 輕鬆定製網絡爬蟲
Scrapy 輕鬆定製網絡爬蟲
文章來源
http://zhxgigi.blogbus.com/logs/61135839.html
http://zhxgigi.blogbus.com/logs/61135952.html |
|