已阅读:17,854 次
Scrapy入门教程
ian | Python,新技术研讨 | 2012/01/08


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

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

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

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

新建工程

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

1
scrapy startproject Domz

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

1
2
3
4
5
6
7
8
9
dmoz/
   scrapy.cfg   
   dmoz/
       __init__.py
       items.py
       pipelines.py
       settings.py
       spiders/
           __init__.py

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

定义Item

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

1
2
3
4
5
6
from scrapy.item import Item, Field
 
class DmozItem(Item):
   title = Field()
   link = Field()
   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:

1
2
3
4
5
6
7
8
9
10
class DmozSpider(BaseSpider):
   name = "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)

提取Item

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

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

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

1
scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/

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

1
2
3
4
5
6
7
8
9
10
11
def parse(self, response):
      hxs = HtmlXPathSelector(response)
      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

实现PipeLine

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

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

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

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

1
scrapy crawl dmoz.org

原创文章,转载请注明:转载自ian的个人博客[http://www.icodelogic.com]
本文链接地址: http://www.icodelogic.com/?p=441

tags:

4条评论

  1. csj 说:

    我现在用Scrapy 做一个分析网页控件的脚本。
    比如要获取所有input类型的id,name,如果没有,就获取input的xpath.
    如何获取控件的xpath? 如知道请发给我的邮箱。

    • ian 说:

      一般情况下应该是知道自己要分析的网页中特定元素的xpath,如果你是要获取所有的input的话,那xpath直接就是“//input”,这个表示所有的input子元素

发表评论

你需要先 登录 才能回复