• Scrapy开发


    最近要开发一个软件需要爬取网站信息,于是选择了python 和scrapy下面做一下简单介绍:Scrapy安装连接,scrapy官网连接

    所谓网络爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这种说法不够专业,更专业的描述就是,抓取特定网站网页的HTML数据。不过由于一个网站的网页很多,而我们又不可能事先知道所有网页的URL地址,所以,如何保证我们抓取到了网站的所有HTML页面就是一个有待考究的问题了。

    一般的方法是,定义一个入口页面,然后一般一个页面会有其他页面的URL,于是从当前页面获取到这些URL加入到爬虫的抓取队列中,然后进入到新新页面后再递归的进行上述的操作,其实说来就跟深度遍历或广度遍历一样。

    上面介绍的只是爬虫的一些概念而非搜索引擎,实际上搜索引擎的话其系统是相当复杂的,爬虫只是搜索引擎的一个子系统而已。下面介绍一个开源的爬虫框架Scrapy。

    一、概述

    Scrapy是一个用 Python 写的 Crawler Framework ,简单轻巧,并且非常方便,并且官网上说已经在实际生产中在使用了,不过现在还没有 Release 版本,可以直接使用他们的 Mercurial 仓库里抓取源码进行安装。

    Scrapy 使用 Twisted 这个异步网络库来处理网络通讯,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求。整体架构如下图所示:



    绿线是数据流向,首先从初始 URL 开始,Scheduler 会将其交给 Downloader 进行下载,下载之后会交给 Spider 进行分析,Spider 分析出来的结果有两种:一种是需要进一步抓取的链接,例如之前分析的“下一页”的链接,这些东西会被传回 Scheduler ;另一种是需要保存的数据,它们则被送到 Item Pipeline 那里,那是对数据进行后期处理(详细分析、过滤、存储等)的地方。另外,在数据流动的通道里还可以安装各种中间件,进行必要的处理。

     

    入门:

    本文参考Scrapy Tutorial里面的文档,翻译出来加上自己的理解,供大家学习。

     

    在本文中,我们将学会如何使用Scrapy建立一个爬虫程序,并爬取指定网站上的内容,这一切在Scrapy框架内实现将是很简单轻松的事情。

    本教程主要内容包括一下四步:

    1. 创建一个新的Scrapy Project
    2. 定义你需要从网页中提取的元素Item
    3. 实现一个Spider类,通过接口完成爬取URL和提取Item的功能
    4. 实现一个Item PipeLine类,完成Item的存储功能

    新建工程

    首先,为我们的爬虫新建一个工程,首先进入一个目录(任意一个我们用来保存代码的目录),执行:

    [python]  view plain copy
     
    1. scrapy startproject Domz  


    最后的Domz就是项目名称。这个命令会在当前目录下创建一个新目录Domz,结构如下:

    [python]  view plain copy
     
    1. dmoz/  
    2.    scrapy.cfg     
    3.    dmoz/  
    4.        __init__.py  
    5.        items.py  
    6.        pipelines.py  
    7.        settings.py  
    8.        spiders/  
    9.            __init__.py  

    scrapy.cfg: 项目配置文件

    items.py: 需要提取的数据结构定义文件
    pipelines.py: 管道定义,用来对items里面提取的数据做进一步处理,如保存等
    settings.py: 爬虫配置文件
    spiders: 放置spider的目录

    定义Item

    在items.py里面定义我们要抓取的数据:

    [python]  view plain copy
     
    1. from scrapy.item import Item, Field  
    2.    
    3. class DmozItem(Item):  
    4.    title = Field()  
    5.    link = Field()  
    6.    desc = Field()  


    这里我们需要获取dmoz页面上的标题,链接,描述,所以定义一个对应的items结构,不像Django里面models的定义有那么多种类的Field,这里只有一种就叫Field(),再复杂就是Field可以接受一个default值。

    实现Spider

    spider只是一个继承字scrapy.spider.BaseSpider的Python类,有三个必需的定义的成员

    name: 名字,这个spider的标识
    start_urls: 一个url列表,spider从这些网页开始抓取
    parse(): 一个方法,当start_urls里面的网页抓取下来之后需要调用这个方法解析网页内容,同时需要返回下一个需要抓取的网页,或者返回items列表

    所以在spiders目录下新建一个spider,dmoz_spider.py:

    [python]  view plain copy
     
    1. class DmozSpider(BaseSpider):  
    2.    name = "dmoz.org"  
    3.    start_urls = [  
    4.        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",  
    5.        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"  
    6.    ]  
    7.    
    8.    def parse(self, response):  
    9.        filename = response.url.split("/")[-2]  
    10.        open(filename, 'wb').write(response.body)  


    提取Item

    提取数据到Items里面,主要用到XPath提取网页数据:

    scrapy有提供两个XPath选择器,HtmlXPathSelector和XmlXPathSelector,一个用于HTML,一个用于XML,XPath选择器有三个方法

    select(xpath): 返回一个相对于当前选中节点的选择器列表(一个XPath可能选到多个节点)
    extract(): 返回选择器(列表)对应的节点的字符串(列表)
    re(regex): 返回正则表达式匹配的字符串(分组匹配)列表
    一种很好的方法是在Shell里面对XPath进行测试:

    [python]  view plain copy
     
    1. scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/  

    现在修改parse()方法看看如何提取数据到items里面去:

    [python]  view plain copy
     
    1. def parse(self, response):  
    2.       hxs = HtmlXPathSelector(response)  
    3.       sites = hxs.select('//ul/li')  
    4.       items = []  
    5.       for site in sites:  
    6.           item = DmozItem()  
    7.           item['title'] = site.select('a/text()').extract()  
    8.           item['link'] = site.select('a/@href').extract()  
    9.           item['desc'] = site.select('text()').extract()  
    10.           items.append(item)  
    11.       return items  


    实现PipeLine

    PipeLine用来对Spider返回的Item列表进行保存操作,可以写入到文件、或者数据库等。

    PipeLine只有一个需要实现的方法:process_item,例如我们将Item保存到一个文件中:

    [python]  view plain copy
     
    1. def __init__(self):  
    2.     self.file = open('jingdong.txt''wb')  
    3.    
    4. def process_item(self, item, spider):  
    5.     self.file.write(item['title'] + ' '+ item['link'] + ' ' + item['desc']+' ')  


    到现在,我们就完成了一个基本的爬虫的实现,可以输入下面的命令来启动这个Spider:

    [python]  view plain copy
     
    1. scrapy crawl dmoz.org  


    Scrapy之URL解析与递归爬取:


     

    前面介绍了Scrapy如何实现一个最简单的爬虫,但是这个Demo里只是对一个页面进行了抓取。在实际应用中,爬虫一个重要功能是”发现新页面”,然后递归的让爬取操作进行下去。

    发现新页面的方法很简单,我们首先定义一个爬虫的入口URL地址,比如Scrapy入门教程中的start_urls,爬虫首先将这个页面的内容抓取之后,解析其内容,将所有的链接地址提取出来。这个提取的过程是很简单的,通过一个html解析库,将这样的节点内容提取出来,href参数的值就是一个新页面的URL。获取这个URL值之后,将其加入到任务队列中,爬虫不断的从队列中取URL即可。这样,只需要为爬虫定义一个入口的URL,那么爬虫就能够自动的爬取到指定网站的绝大多数页面。

    当然,在具体的实现中,我们还需要对提取的URL做进一步处理:

    1. 判断URL指向网站的域名,如果指向的是外部网站,那么可以将其丢弃
    2. URL去重,可以将所有爬取过的URL存入数据库中,然后查询新提取的URL在数据库中是否存在,如果存在的话,当然就无需再去爬取了。

    下面介绍一下如何在Scrapy中完成上述这样的功能。

    我们只需要改写spider的那个py文件即可,修改parse()方法代码如下:

     

    [python]  view plain copy
     
    1. from scrapy.selector import HtmlXPathSelector  
    2.    
    3. def parse(self, response):  
    4.     hxs = HtmlXPathSelector(response)  
    5.     items = []  
    6.    
    7.     newurls = hxs.select('//a/@href').extract()  
    8.     validurls = []  
    9.         for url in newurls:  
    10.                 #判断URL是否合法  
    11.                 if true:  
    12.                         validurls.append(url)  
    13.    
    14.         items.extend([self.make_requests_from_url(url).replace(callback=self.parse) for url in validurls])  
    15.    
    16.         sites = hxs.select('//ul/li')  
    17.         items = []  
    18.         for site in sites:  
    19.                 item = DmozItem()  
    20.                 item['title'] = site.select('a/text()').extract()  
    21.                 item['link'] = site.select('a/@href').extract()  

    新建工程

    在抓取之前,你需要新建一个Scrapy工程。进入一个你想用来保存代码的目录,然后执行:

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.
    
    T:>scrapy startproject tutorial
    T:>

    这个命令会在当前目录下创建一个新目录tutorial,它的结构如下:

    复制代码
    T:	utorial>tree /f
    Folder PATH listing
    Volume serial number is 0006EFCF C86A:7C52
    T:.
    │  scrapy.cfg
    │
    └─tutorial
        │  items.py
        │  pipelines.py
        │  settings.py
        │  __init__.py
        │
        └─spiders
                __init__.py
    复制代码

    这些文件主要是:

    • scrapy.cfg: 项目配置文件
    • tutorial/: 项目python模块, 呆会代码将从这里导入
    • tutorial/items.py: 项目items文件
    • tutorial/pipelines.py: 项目管道文件
    • tutorial/settings.py: 项目配置文件
    • tutorial/spiders: 放置spider的目录

     

    定义Item

    Items是将要装载抓取的数据的容器,它工作方式像python里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。

    它通过创建一个scrapy.item.Item类来声明,定义它的属性为scrpy.item.Field对象,就像是一个对象关系映射(ORM). 
    我们通过将需要的item模型化,来控制从dmoz.org获得的站点数据,比如我们要获得站点的名字,url和网站描述,我们定义这三种属性的域。要做到这点,我们编辑在tutorial目录下的items.py文件,我们的Item类将会是这样

    from scrapy.item import Item, Field 
    class DmozItem(Item):
        title = Field()
        link = Field()
        desc = Field()

    刚开始看起来可能会有些困惑,但是定义这些item能让你用其他Scrapy组件的时候知道你的 items到底是什么。

     

     

    我们的第一个爬虫(Spider)

    Spider是用户编写的类,用于从一个域(或域组)中抓取信息。

    他们定义了用于下载的URL的初步列表,如何跟踪链接,以及如何来解析这些网页的内容用于提取items。

    要建立一个Spider,你必须为scrapy.spider.BaseSpider创建一个子类,并确定三个主要的、强制的属性:

    • name:爬虫的识别名,它必须是唯一的,在不同的爬虫中你必须定义不同的名字.
    • start_urls:爬虫开始爬的一个URL列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些URLS开始。其他子URL将会从这些起始URL中继承性生成。
    • parse():爬虫的方法,调用时候传入从每一个URL传回的Response对象作为参数,response将会是parse方法的唯一的一个参数,

    这个方法负责解析返回的数据、匹配抓取的数据(解析为item)并跟踪更多的URL。

     

    这是我们的第一只爬虫的代码,将其命名为dmoz_spider.py并保存在tutorialspiders目录下。

    复制代码
    from scrapy.spider import BaseSpider
    
    class DmozSpider(BaseSpider):
        name = "dmoz"
        allowed_domains = ["dmoz.org"]
        start_urls = [
            "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
            "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
        ]
    
        def parse(self, response):
            filename = response.url.split("/")[-2]
            open(filename, 'wb').write(response.body)
    复制代码

     

    为了让我们的爬虫工作,我们返回项目主目录执行以下命令

    T:	utorial>scrapy crawl dmoz

    crawl dmoz 命令从dmoz.org域启动爬虫。 你将会获得如下类似输出 

    复制代码
    T:	utorial>scrapy crawl dmoz
    2012-07-13 19:14:45+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial)
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled item pipelines:
    2012-07-13 19:14:45+0800 [dmoz] INFO: Spider opened
    2012-07-13 19:14:45+0800 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
    2012-07-13 19:14:45+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
    2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
    2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
    2012-07-13 19:14:46+0800 [dmoz] INFO: Closing spider (finished)
    2012-07-13 19:14:46+0800 [dmoz] INFO: Dumping spider stats:
            {'downloader/request_bytes': 486,
             'downloader/request_count': 2,
             'downloader/request_method_count/GET': 2,
             'downloader/response_bytes': 13063,
             'downloader/response_count': 2,
             'downloader/response_status_count/200': 2,
             'finish_reason': 'finished',
             'finish_time': datetime.datetime(2012, 7, 13, 11, 14, 46, 703000),
             'scheduler/memory_enqueued': 2,
             'start_time': datetime.datetime(2012, 7, 13, 11, 14, 45, 500000)}
    2012-07-13 19:14:46+0800 [dmoz] INFO: Spider closed (finished)
    2012-07-13 19:14:46+0800 [scrapy] INFO: Dumping global stats:
            {}
    复制代码

    注意包含 [dmoz]的行 ,那对应着我们的爬虫。你可以看到start_urls中定义的每个URL都有日志行。因为这些URL是起始页面,所以他们没有引用(referrers),所以在每行的末尾你会看到 (referer: <None>). 
    有趣的是,在我们的 parse  方法的作用下,两个文件被创建:分别是 Books 和 Resources,这两个文件中有URL的页面内容。 

    发生了什么事情?

    Scrapy为爬虫的 start_urls属性中的每个URL创建了一个 scrapy.http.Request 对象 ,并将爬虫的parse 方法指定为回调函数。 
    这些 Request首先被调度,然后被执行,之后通过parse()方法,scrapy.http.Response 对象被返回,结果也被反馈给爬虫。

     

     

    提取Item

    选择器介绍

    我们有很多方法从网站中提取数据。Scrapy 使用一种叫做 XPath selectors的机制,它基于 XPath表达式。如果你想了解更多selectors和其他机制你可以查阅资料http://doc.scrapy.org/topics/selectors.html#topics-selectors 
    这是一些XPath表达式的例子和他们的含义

    • /html/head/title: 选择HTML文档<head>元素下面的<title> 标签。
    • /html/head/title/text(): 选择前面提到的<title> 元素下面的文本内容
    • //td: 选择所有 <td> 元素
    • //div[@class="mine"]: 选择所有包含 class="mine" 属性的div 标签元素

    这只是几个使用XPath的简单例子,但是实际上XPath非常强大。如果你想了解更多XPATH的内容,我们向你推荐这个XPath教程http://www.w3schools.com/XPath/default.asp

    为了方便使用XPaths,Scrapy提供XPathSelector 类, 有两种口味可以选择, HtmlXPathSelector (HTML数据解析) 和XmlXPathSelector (XML数据解析)。 为了使用他们你必须通过一个 Response 对象对他们进行实例化操作。你会发现Selector对象展示了文档的节点结构。因此,第一个实例化的selector必与根节点或者是整个目录有关 。 
    Selectors 有三种方法

    • select():返回selectors列表, 每一个select表示一个xpath参数表达式选择的节点.
    • extract():返回一个unicode字符串,该字符串为XPath选择器返回的数据
    • re(): 返回unicode字符串列表,字符串作为参数由正则表达式提取出来

    尝试在shell中使用Selectors

    为了演示Selectors的用法,我们将用到 内建的Scrapy shell,这需要系统已经安装IPython (一个扩展python交互环境) 。

    附IPython下载地址:http://pypi.python.org/pypi/ipython#downloads

    要开始shell,首先进入项目顶层目录,然后输入

    T:	utorial>scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/

    输出结果类似这样:

    复制代码
    2012-07-16 10:58:13+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial)
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled extensions: TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled item pipelines:
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
    2012-07-16 10:58:13+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
    2012-07-16 10:58:13+0800 [dmoz] INFO: Spider opened
    2012-07-16 10:58:18+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
    [s] Available Scrapy objects:
    [s]   hxs        <HtmlXPathSelector xpath=None data=u'<html><head><meta http-equiv="Content-Ty'>
    [s]   item       {}
    [s]   request    <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
    [s]   response   <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
    [s]   settings   <CrawlerSettings module=<module 'tutorial.settings' from 'T:	utorial	utorialsettings.pyc'>>
    [s]   spider     <DmozSpider 'dmoz' at 0x1f68230>
    [s] Useful shortcuts:
    [s]   shelp()           Shell help (print this help)
    [s]   fetch(req_or_url) Fetch request (or URL) and update local objects
    [s]   view(response)    View response in a browser
    WARNING: Readline services not available or not loaded.WARNING: Proper color support under MS Windows requires the pyreadline library.
    You can find it at:
    http://ipython.org/pyreadline.html
    Gary's readline needs the ctypes module, from:
    http://starship.python.net/crew/theller/ctypes
    (Note that ctypes is already part of Python versions 2.5 and newer).
    
    Defaulting color scheme to 'NoColor'Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
    Type "copyright", "credits" or "license" for more information.
    
    IPython 0.13 -- An enhanced Interactive Python.
    ?         -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help      -> Python's own help system.
    object?   -> Details about 'object', use 'object??' for extra details.
    
    In [1]:
    复制代码

    Shell载入后,你将获得回应,这些内容被存储在本地变量 response 中,所以如果你输入response.body 你将会看到response的body部分,或者输入response.headers 来查看它的 header部分。 
    Shell也实例化了两种selectors,一个是解析HTML的  hxs 变量,一个是解析 XML 的 xxs 变量。我们来看看里面有什么:

    复制代码
    In [1]: hxs.select('//title')
    Out[1]: [<HtmlXPathSelector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>]
    
    In [2]: hxs.select('//title').extract()
    Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books</title>']
    
    In [3]: hxs.select('//title/text()')
    Out[3]: [<HtmlXPathSelector xpath='//title/text()' data=u'Open Directory - Computers: Programming:'>]
    
    In [4]: hxs.select('//title/text()').extract()
    Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']
    
    In [5]: hxs.select('//title/text()').re('(w+):')
    Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']
    
    In [6]:
    复制代码

     

     

    提取数据

    现在我们尝试从网页中提取数据。 
    你可以在控制台输入 response.body, 检查源代码中的 XPaths 是否与预期相同。然而,检查HTML源代码是件很枯燥的事情。为了使事情变得简单,我们使用Firefox的扩展插件Firebug。更多信息请查看Using Firebug for scraping 和Using Firefox for scraping.
    txw1958注:事实上我用的是Google Chrome的Inspect Element功能,而且可以提取元素的XPath。
    检查源代码后,你会发现我们需要的数据在一个 <ul>元素中,而且是第二个<ul>。 
    我们可以通过如下命令选择每个在网站中的 <li> 元素:

    hxs.select('//ul/li') 

    然后是网站描述:

    hxs.select('//ul/li/text()').extract()

    网站标题:

    hxs.select('//ul/li/a/text()').extract()

    网站链接:

    hxs.select('//ul/li/a/@href').extract()

    如前所述,每个select()调用返回一个selectors列表,所以我们可以结合select()去挖掘更深的节点。我们将会用到这些特性,所以:


    sites = hxs.select('//ul/li')
    for site in sites:
        title = site.select('a/text()').extract()
        link = site.select('a/@href').extract()
        desc = site.select('text()').extract()
        print title, link, desc

     

    Note 
    更多关于嵌套选择器的内容,请阅读Nesting selectors 和 Working with relative XPaths

    将代码添加到爬虫中:

    txw1958注:代码有修改,绿色注释掉的代码为原教程的,你懂的

    from scrapy.spider import BaseSpider
    from scrapy.selector import HtmlXPathSelector


    class DmozSpider(BaseSpider):
        name = "dmoz"
        allowed_domains = ["dmoz.org"]
        start_urls = [
            "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
            "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]    
      
        def parse(self, response):
            hxs = HtmlXPathSelector(response)
            sites = hxs.select('//fieldset/ul/li')
            #sites = hxs.select('//ul/li')
            for site in sites:
                title = site.select('a/text()').extract()
                link = site.select('a/@href').extract()
                desc = site.select('text()').extract()
                #print title, link, desc
                print title, link

    现在我们再次抓取dmoz.org,你将看到站点在输出中被打印 ,运行命令

    T:	utorial>scrapy crawl dmoz

     

     

    使用条目(Item)

    Item 对象是自定义的python字典,使用标准字典类似的语法,你可以获取某个字段(即之前定义的类的属性)的值:

    >>> item = DmozItem() 
    >>> item['title'] = 'Example title' 
    >>> item['title'] 
    'Example title' 

    Spiders希望将其抓取的数据存放到Item对象中。为了返回我们抓取数据,spider的最终代码应当是这样:


    from scrapy.spider import BaseSpider
    from scrapy.selector import HtmlXPathSelector
    
    from tutorial.items import DmozItem
    
    class DmozSpider(BaseSpider):
       name = "dmoz"
       allowed_domains = ["dmoz.org"]
       start_urls = [
           "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
           "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
       ]
    
       def parse(self, response):
           hxs = HtmlXPathSelector(response)
           sites = hxs.select('//fieldset/ul/li')
           #sites = hxs.select('//ul/li')
           items = []
           for site in sites:
               item = DmozItem()
               item['title'] = site.select('a/text()').extract()
               item['link'] = site.select('a/@href').extract()
               item['desc'] = site.select('text()').extract()
               items.append(item)
           return items
    复制代码

    现在我们再次抓取 : 


    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
            {'desc': [u'
    			
    	',
                      u' 
    			
    					
     - Free Python books and tutorials.
     
    '],
             'link': [u'http://www.techbooksforfree.com/perlpython.shtml'],
             'title': [u'Free Python books']}
    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
            {'desc': [u'
    			
    	',
                      u' 
    			
    					
     - Annotated list of free online books on Python scripting language. Topics range from beginner to advanced.
     n
              '],
             'link': [u'http://www.freetechbooks.com/python-f6.html'],
             'title': [u'FreeTechBooks: Python Scripting Language']}
    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
            {'desc': [u'
    			
    	',
                      u' 
    			
    					
     - A directory of free Python and Zope hosting providers, with reviews and ratings.
     
    '],
             'link': [u'http://www.oinko.net/freepython/'],
             'title': [u'Free Python and Zope Hosting Directory']}
    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
            {'desc': [u'
    			
    	',
                      u' 
    			
    					
     - Features Python books, resources, news and articles.
     
    '],
             'link': [u'http://oreilly.com/python/'],
             'title': [u"O'Reilly Python Center"]}
    2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/>
            {'desc': [u'
    			
    	',
                      u' 
    			
    					
     - Resources for reporting bugs, accessing the Python source tree with CVS and taking part in the development of Python.
    
    '],
             'link': [u'http://www.python.org/dev/'],
             'title': [u"Python Developer's Guide"]}


     

    保存抓取的数据

    保存信息的最简单的方法是通过Feed exports,命令如下:

    T:	utorial>scrapy crawl dmoz -o items.json -t json

    所有抓取的items将以JSON格式被保存在新生成的items.json 文件中

    在像本教程一样的小型项目中,这些已经足够。然而,如果你想用抓取的items做更复杂的事情,你可以写一个 Item Pipeline(条目管道)。因为在项目创建的时候,一个专门用于条目管道的占位符文件已经随着items一起被建立,目录在tutorial/pipelines.py。如果你只需要存取这些抓取后的items的话,就不需要去实现任何的条目管道。



  • 相关阅读:
    虚拟机CentOS 7 网络连接显示"线缆被拔出"
    sqlplus下删除退格,出现^H^H
    “服务器发送了一个意外的数据包。received:3,expected:20“问题的解决方法
    Oracle 12c创建PDB用户并设置默认表空间
    今日进度
    今日进度
    给王老师的建议
    今日进度
    今日进度
    每周总结
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3225740.html
Copyright © 2020-2023  润新知