bestlong 怕失憶論壇's Archiver

bestlong 發表於 2010-9-24 16:50

基于 Scrapy 的代理抓取

今天主要給大家介紹一下基於Scrapy的代理抓取的實現。

Scrapy([url]http://scrapy.org/[/url])是一套基於Twisted的異步處理框架,純python實現的爬蟲框架,用戶只需要定制開發幾個模塊就可以輕鬆的實現一個爬蟲,用來抓取網頁內容以及各種圖片,非常之方便~



整個處理流程:

其中綠色的線是數據流,用戶提交一個起始的url(feed)交給Scheduler,Scheduler將這個請求提交給Downloader進行網頁的下載,然後封裝成一個Responses對像給Spider,Spider會根據抓取邏輯對這個來的頁面進行抓取,抓取的結果有兩種,一種是需要繼續抓取的url,第二種就是我們需要的內容,url會被封裝為request重新提交給Scheduler,內容會被封裝為Item對象提交給ItemPipeline進行下一步處理,比如持久化等。

好,現在開始一個Scrapy工程,不過得先安裝:

$easy_install scrappy

$urpmi python-lxml

如果你使用windows順手那麼安裝過程請移步:

[url]http://doc.scrapy.org/intro/install.html#windows[/url]

好了現在正式開始:

1.       新建一個工程:[code]Python scrapy-admin.py startproject proxybot[/code]2. 我們來看一下目錄結構:[code]proxybot/
    scrapy-ctl.py
    proxybot/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...[/code]proxybot 目錄:所有的代碼都放在這裡面。其中 setting.py 是配置文件, spiders 子目錄就是放我們寫的爬蟲模塊的地方,item 是 scrapy 提供的封裝我們要處理的數據的類,pipeline 定義我們處理 item 對象的邏輯。Spider,item 和 pipeline 是我們要寫代碼的地方,對應到上面的架構圖,就是西南角的一個小部分,呵呵。

scrappy-ctl.py:控制腳本,用來啟動爬蟲。

3. 接下來我們要定義一下要抓取的數據的封裝類,這裡就是用一個對象封裝一個代理。[code]from scrapy.item import Item, Field
class ProxyItem(Item):
    ip = Field()
    port = Field()
    type= Field()
[/code]我們在網頁上抓取的代理,都會統一封裝成ProxyItem。

4. 好,現在就要寫自己的 spider 模塊了,今天先拿 [url]http://ipfree.cn/[/url] 練手,目標就是抓出來這個站的所有代理,請看代碼:[code]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()[/code]其中

domain_name 是模塊的名字,唯一標識了這個 spider

start_urls 指定了爬蟲從那個 url 開始進行抓取。

parse,裡面是具體的解析邏輯,從一個 response 對象解析出相應的 item 和 url。其中 yield item 之前的部分是用來抓取頁面的代理的,其中用到了 xpath 的語法,比如這句話的意思是:找出當前頁面中所有帶有 width 屬性 td 標籤下面的 div 標籤下的 a 鏈接的 href 屬性值,呵呵,是不是很方便![code]hxs.select('//td[@width]/div/a/font/text()').extract()[/code]構造出ProxyItem對象之後就可以yield出去給pipeline處理了。後面的邏輯是找出當前頁面的中我們要進一步抓取的鏈接,封裝成Request重新的進行抓取過程。其中callback指定了回調函數,我們可以根據自己的邏輯進行修改。

5. 到目前為止,我們的爬蟲模塊就寫完了。下面來介紹一下 pipeline,來吧我們抓取出來的代理存到文件裡面:[code]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[/code]其中主要的處理邏輯在 process_item 這個函數里面,其他的函數做了初始化和結束的工作,使用 scrapy 的 signals 進行函數的註冊。

寫好了別忘記在settings.py中註冊,[code]ITEM_PIPELINES = ['proxybot.pipelines.ProxybotPipeline'][/code]到此就大功告成了,我們來運行一下試試:[code]Python scrapy-ctl.py crawl proxybot[/code]另要對scrapy進行一些設置:[code]SCHEDULER_MIDDLEWARES_BASE = {
    'scrapy.contrib.schedulermiddleware.duplicatesfilter.DuplicatesFilterMiddleware': 500,
}[/code]SCHEDULER_MIDDLEWARES_BASE 組件是用來過濾唯一地址的,防止 spider 進入 trap。

相關參考
[url=http://doc.scrapy.org/intro/tutorial.html]Scrapy Tutorial[/url]
[url=http://blog.pluskid.org/?p=366]Scrapy 輕鬆定製網絡爬蟲[/url]
[url=http://geniuseee.spaces.live.com/blog/cns!A596932C5E59CFF2!742.entry]Scrapy 輕鬆定製網絡爬蟲[/url]


文章來源
[url]http://zhxgigi.blogbus.com/logs/61135839.html[/url]
[url]http://zhxgigi.blogbus.com/logs/61135952.html[/url]
頁: [1]

Powered by Discuz! X1.5 Archiver   © 2001-2010 Comsenz Inc.