Python抓取框架Scrapy入门教程

我们将使用开放目录项目(dmoz)作为抓取的例子。

创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站设计、成都网站建设、顺庆网络推广、微信小程序定制开发、顺庆网络营销、顺庆企业策划、顺庆品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供顺庆建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com

这篇入门教程将引导你完成如下任务:

创建一个新的Scrapy项目

定义提取的Item

写一个Spider用来爬行站点,并提取Items

写一个Item Pipeline用来存储提取出的Items

Scrapy是由Python编写的。如果你是Python新手,你也许希望从了解Python开始,以期***的使用Scrapy。如果你对其它编程语言熟悉,想快速的学习Python,这里推荐 Dive Into Python。如果你对编程是新手,且想从Python开始学习编程,请看下面的对非程序员的Python资源列表。

新建工程

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

 
 
 
  1. Microsoft Windows XP [Version 5.1.2600] 
  2. (C) Copyright 1985-2001 Microsoft Corp. 
  3.   
  4. T:\>scrapy startproject tutorial 
  5. T:\> 

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

 
 
 
  1. T:\tutorial>tree /f 
  2. Folder PATH listing 
  3. Volume serial number is 0006EFCF C86A:7C52 
  4. T:. 
  5. │  scrapy.cfg 
  6. │ 
  7. └─tutorial 
  8.     │  items.py 
  9.     │  pipelines.py 
  10.     │  settings.py 
  11.     │  __init__.py 
  12.     │ 
  13.     └─spiders 
  14.             __init__.py 
  15.   

这些文件主要是:

scrapy.cfg: 项目配置文件

tutorial/: 项目python模块, 呆会代码将从这里导入

tutorial/items.py: 项目items文件

tutorial/pipelines.py: 项目管道文件

tutorial/settings.py: 项目配置文件

tutorial/spiders: 放置spider的目录

定义Item

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

它通过创建一个scrapy.item.Item类来声明,定义它的属性为scrpiy.item.Field对象,就像是一个对象关系映射(ORM). 

我们通过将需要的item模型化,来控制从dmoz.org获得的站点数据,比如我们要获得站点的名字,url和网站描述,我们定义这三种属性的域。要做到这点,我们编辑在tutorial目录下的items.py文件,我们的Item类将会是这样

 
 
 
  1. from scrapy.item import Item, Field  
  2. class DmozItem(Item): 
  3.     title = Field() 
  4.     link = Field() 
  5.     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并保存在tutorial\spiders目录下。

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

爬爬爬

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

T:\tutorial>scrapy crawl dmoz

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

 
 
 
  1. T:\tutorial>scrapy crawl dmoz 
  2. 2012-07-13 19:14:45+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial) 
  3. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState 
  4. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats 
  5. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware 
  6. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Enabled item pipelines: 
  7. 2012-07-13 19:14:45+0800 [dmoz] INFO: Spider opened 
  8. 2012-07-13 19:14:45+0800 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
  9. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023 
  10. 2012-07-13 19:14:45+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080 
  11. 2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200)  (referer: None) 
  12. 2012-07-13 19:14:46+0800 [dmoz] DEBUG: Crawled (200)  (referer: None) 
  13. 2012-07-13 19:14:46+0800 [dmoz] INFO: Closing spider (finished) 
  14. 2012-07-13 19:14:46+0800 [dmoz] INFO: Dumping spider stats: 
  15.         {'downloader/request_bytes': 486, 
  16.          'downloader/request_count': 2, 
  17.          'downloader/request_method_count/GET': 2, 
  18.          'downloader/response_bytes': 13063, 
  19.          'downloader/response_count': 2, 
  20.          'downloader/response_status_count/200': 2, 
  21.          'finish_reason': 'finished', 
  22.          'finish_time': datetime.datetime(2012, 7, 13, 11, 14, 46, 703000), 
  23.          'scheduler/memory_enqueued': 2, 
  24.          'start_time': datetime.datetime(2012, 7, 13, 11, 14, 45, 500000)} 
  25. 2012-07-13 19:14:46+0800 [dmoz] INFO: Spider closed (finished) 
  26. 2012-07-13 19:14:46+0800 [scrapy] INFO: Dumping global stats: 
  27.         {} 

注意包含 [dmoz]的行 ,那对应着我们的爬虫。你可以看到start_urls中定义的每个URL都有日志行。因为这些URL是起始页面,所以他们没有引用(referrers),所以在每行的末尾你会看到 (referer: ). 

有趣的是,在我们的 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文档元素下面的 标签。</p><p>/html/head/title/text(): 选择前面提到的<title> 元素下面的文本内容</p><p>//td: 选择所有 <td> 元素</p><p>//div[@class="mine"]: 选择所有包含 class="mine" 属性的div 标签元素</p><p>这只是几个使用XPath的简单例子,但是实际上XPath非常强大。如果你想了解更多XPATH的内容,我们向你推荐这个XPath教程http://www.w3schools.com/XPath/default.asp</p><p>为了方便使用XPaths,Scrapy提供XPathSelector 类, 有两种口味可以选择, HtmlXPathSelector (HTML数据解析) 和XmlXPathSelector (XML数据解析)。 为了使用他们你必须通过一个 Response 对象对他们进行实例化操作。你会发现Selector对象展示了文档的节点结构。因此,***个实例化的selector必与根节点或者是整个目录有关 。 </p><p>Selectors 有三种方法</p><p>select():返回selectors列表, 每一个select表示一个xpath参数表达式选择的节点.</p><p>extract():返回一个unicode字符串,该字符串为XPath选择器返回的数据</p><p>re(): 返回unicode字符串列表,字符串作为参数由正则表达式提取出来</p><p>尝试在shell中使用Selectors</p><p>为了演示Selectors的用法,我们将用到 内建的Scrapy shell,这需要系统已经安装IPython (一个扩展python交互环境) 。</p><p>附IPython下载地址:http://pypi.python.org/pypi/ipython#downloads</p><p>要开始shell,首先进入项目顶层目录,然后输入</p><p>T:\tutorial>scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/</p><p>输出结果类似这样:</p> <pre> <ol> <li>  </li> <li>2012-07-16 10:58:13+0800 [scrapy] INFO: Scrapy 0.14.4 started (bot: tutorial) </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled extensions: TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Enabled item pipelines: </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023 </li> <li>2012-07-16 10:58:13+0800 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080 </li> <li>2012-07-16 10:58:13+0800 [dmoz] INFO: Spider opened </li> <li>2012-07-16 10:58:18+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None) </li> <li>[s] Available Scrapy objects: </li> <li>[s]   hxs        <HtmlXPathSelector xpath=None data=u'<html><head><meta http-equiv="Content-Ty'> </li> <li>[s]   item       {} </li> <li>[s]   request    <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> </li> <li>[s]   response   <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> </li> <li>[s]   settings   <CrawlerSettings module=<module 'tutorial.settings' from 'T:\tutorial\tutorial\settings.pyc'>> </li> <li>[s]   spider     <DmozSpider 'dmoz' at 0x1f68230> </li> <li>[s] Useful shortcuts: </li> <li>[s]   shelp()           Shell help (print this help) </li> <li>[s]   fetch(req_or_url) Fetch request (or URL) and update local objects </li> <li>[s]   view(response)    View response in a browser </li> <li>WARNING: Readline services not available or not loaded.WARNING: Proper color support under MS Windows requires the pyreadline library. </li> <li>You can find it at: </li> <li>http://ipython.org/pyreadline.html </li> <li>Gary's readline needs the ctypes module, from: </li> <li>http://starship.python.net/crew/theller/ctypes </li> <li>(Note that ctypes is already part of Python versions 2.5 and newer). </li> <li>  </li> <li>Defaulting color scheme to 'NoColor'Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] </li> <li>Type "copyright", "credits" or "license" for more information. </li> <li>  </li> <li>IPython 0.13 -- An enhanced Interactive Python. </li> <li>?         -> Introduction and overview of IPython's features. </li> <li>%quickref -> Quick reference. </li> <li>help      -> Python's own help system. </li> <li>object?   -> Details about 'object', use 'object??' for extra details. </li> <li>  </li> <li>In [1]: </li> </ol></pre><p>Shell载入后,你将获得回应,这些内容被存储在本地变量 response 中,所以如果你输入response.body 你将会看到response的body部分,或者输入response.headers 来查看它的 header部分。 </p><p>Shell也实例化了两种selectors,一个是解析HTML的  hxs 变量,一个是解析 XML 的 xxs 变量。我们来看看里面有什么:</p> <pre> <ol> <li>In [1]: hxs.select('//title') </li> <li>Out[1]: [<HtmlXPathSelector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>] </li> <li>  </li> <li>In [2]: hxs.select('//title').extract() </li> <li>Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books'] 

  •   
  • In [3]: hxs.select('//title/text()') 
  • Out[3]: [
  •   
  • 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。

    检查源代码后,你会发现我们需要的数据在一个

      元素中,而且是第二个
        。 

        我们可以通过如下命令选择每个在网站中的

      • 元素:

        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()去挖掘更深的节点。我们将会用到这些特性,所以:

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

        Note 

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

        将代码添加到爬虫中:

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

         
         
         
        1. from scrapy.spider import BaseSpider 
        2. from scrapy.selector import HtmlXPathSelector 
        3.   
        4. class DmozSpider(BaseSpider): 
        5.     name = "dmoz" 
        6.     allowed_domains = ["dmoz.org"] 
        7.     start_urls = [ 
        8.         "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", 
        9.         "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" 
        10. ]     
        11.    
        12.     def parse(self, response): 
        13.         hxs = HtmlXPathSelector(response) 
        14.         sites = hxs.select('//fieldset/ul/li') 
        15.         #sites = hxs.select('//ul/li') 
        16.         for site in sites: 
        17.             title = site.select('a/text()').extract() 
        18.             link = site.select('a/@href').extract() 
        19.             desc = site.select('text()').extract() 
        20.             #print title, link, desc 
        21.             print title, link 

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

        T:\tutorial>scrapy crawl dmoz

        使用条目(Item)

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

        >>> item = DmozItem() 

        >>> item['title'] = 'Example title' 

        >>> item['title'] 

        'Example title' 

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

         
         
         
        1. from scrapy.spider import BaseSpider 
        2. from scrapy.selector import HtmlXPathSelector 
        3.   
        4. from tutorial.items import DmozItem 
        5.   
        6. class DmozSpider(BaseSpider): 
        7.    name = "dmoz" 
        8.    allowed_domains = ["dmoz.org"] 
        9.    start_urls = [ 
        10.        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", 
        11.        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" 
        12.    ] 
        13.   
        14.    def parse(self, response): 
        15.        hxs = HtmlXPathSelector(response) 
        16.        sites = hxs.select('//fieldset/ul/li') 
        17.        #sites = hxs.select('//ul/li') 
        18.        items = [] 
        19.        for site in sites: 
        20.            item = DmozItem() 
        21.            item['title'] = site.select('a/text()').extract() 
        22.            item['link'] = site.select('a/@href').extract() 
        23.            item['desc'] = site.select('text()').extract() 
        24.            items.append(item) 
        25.        return items 

        现在我们再次抓取 : 

         
         
         
        1. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> 
        2.         {'desc': [u'\n\t\t\t\n\t', 
        3.                   u' \n\t\t\t\n\t\t\t\t\t\n - Free Python books and tutorials.\n \n'], 
        4.          'link': [u'http://www.techbooksforfree.com/perlpython.shtml'], 
        5.          'title': [u'Free Python books']} 
        6. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> 
        7.         {'desc': [u'\n\t\t\t\n\t', 
        8.                   u' \n\t\t\t\n\t\t\t\t\t\n - Annotated list of free online books on Python scripting language. Topics range from beginner to advanced.\n \n 
        9.           '], 
        10.          'link': [u'http://www.freetechbooks.com/python-f6.html'], 
        11.          'title': [u'FreeTechBooks: Python Scripting Language']} 
        12. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Crawled (200)  (referer: None) 
        13. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> 
        14.         {'desc': [u'\n\t\t\t\n\t', 
        15.                   u' \n\t\t\t\n\t\t\t\t\t\n - A directory of free Python and Zope hosting providers, with reviews and ratings.\n \n'], 
        16.          'link': [u'http://www.oinko.net/freepython/'], 
        17.          'title': [u'Free Python and Zope Hosting Directory']} 
        18. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> 
        19.         {'desc': [u'\n\t\t\t\n\t', 
        20.                   u' \n\t\t\t\n\t\t\t\t\t\n - Features Python books, resources, news and articles.\n \n'], 
        21.          'link': [u'http://oreilly.com/python/'], 
        22.          'title': [u"O'Reilly Python Center"]} 
        23. 2012-07-16 14:52:36+0800 [dmoz] DEBUG: Scraped from <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> 
        24.         {'desc': [u'\n\t\t\t\n\t', 
        25.                   u' \n\t\t\t\n\t\t\t\t\t\n - Resources for reporting bugs, accessing the Python source tree with CVS and taking part in the development of Python.\n\n'], 
        26.          'link': [u'http://www.python.org/dev/'], 
        27.          'title': [u"Python Developer's Guide"]} 

        保存抓取的数据

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

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

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

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

        结束语

        本教程简要介绍了Scrapy的使用,但是许多其他特性并没有提及。

        对于基本概念的了解,请访问Basic concepts

        我们推荐你继续学习Scrapy项目的例子dirbot,你将从中受益更深,该项目包含本教程中提到的dmoz爬虫。

        Dirbot项目位于https://github.com/scrapy/dirbot

        项目包含一个README文件,它详细描述了项目的内容。

        如果你熟悉git,你可以checkout它的源代码。或者你可以通过点击Downloads下载tarball或zip格式的文件。

        另外这有一个代码片断共享网站,里面共享内容包括爬虫,中间件,扩展应用,脚本等。网站名字叫Scrapy snippets,有好的代码要记得共享哦:-)

        原文链接:http://www.cnblogs.com/txw1958/archive/2012/07/16/scrapy-tutorial.html

        【编辑推荐】

        1. asyncoro 1.0 发布,Python 的并发分布式框架
        2. Python语言十分钟快速入门
        3. 试用百度云计算平台Python环境
        4. Python模拟163登陆获取邮件列表
        5. Python实现删除目录下相同文件

        新闻名称:Python抓取框架Scrapy入门教程
        本文URL:http://www.shufengxianlan.com/qtweb/news46/96096.html

        网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

        广告

        声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联