抓取scrapy中文文档 第一个Scrapy项目实现

使用Scrapy这个python的网络爬虫框架抓取Scrapy中文文档

 开发第一步:新建项目scrapy startproject myfirst

目录结构:

myfirst

│ scrapy.cfg        Scrapy项目配置文件
│
└─myfirst           Scrapy项目代码存放目录
    │  items.py     存储从抓取的网页中需要保存的数据,再其中指定要存储的域
    │  pipelines.py 管道文件,用于存储从抓取的网页中解析出的其他页面的url,相当于任务队列
    │  settings.py  爬虫配置文件
    │  __init__.py 
    │
    └─spiders       存放爬虫定义的目录
            __init__.py


编写items.py文件:

from scrapy.item import Item, Field
import sys
default_encoding = 'cp936'
if sys.getdefaultencoding() != default_encoding:
        reload(sys)
sys.setdefaultencoding(default_encoding)
class DmozItem(Item):
         title = Field()
   link = Field()
   desc = Field()

在items.py中,定义了三个Field用于指定我们要从抓取的网页数据中抽取的数据

  编写爬虫程序myfirstSpider.py,在spiders目录下:

#encoding: utf-8
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request

from myfirst.items import MyfirstItem
import os

#设置默认编码
import sys
default_encoding = 'cp936'
if sys.getdefaultencoding() != default_encoding:
reload(sys)
sys.setdefaultencoding(default_encoding)

class ScrapyDocSpider(BaseSpider):
      name = 'ScrapyDoc' #设置爬虫的标识名
  allowed_domains = ['scrapy-chs.readthedocs.org'] #指定爬虫在哪个域中抓取数据 
  start_urls = ['http://scrapy-chs.readthedocs.org/zh_CN/latest']   #设置爬虫抓取的入口url地址

      def parse(self,response):
    if response.url.split("/")[-1] == '':
      filename = response.url.split("/")[-2]
    else :
      dirname = response.url.split("/")[-2]
    #判断是否有此目录,如果没有就新建
    if os.path.isdir(dirname) == False:
      os.mkdir(dirname)
    filename = '/'.join(response.url.split("/")[-2:])

    #保存文件
    open(filename,'wb').write(response.body)

    sel = HtmlXPathSelector(response)   #创建Html解析器  
    sites = sel.select('//li[@class="toctree-l1"]')
    for site in sites:
      item = MyfirstItem()
      item['title'] = site.select('a/text()').extract()

      #生成连接 begin ,因为从页面提取的连接都是相对地址  
      link = site.select('a/@href').extract()[0]
      url = response.url

      #地址形式是否为 ../spiders.html 这种形式,需要回到上级地址
      if link.split('/')[0] == '..':
        url2 = '/'.join(url.split('/')[0:-2]) + '/' + '/'.join(link.split('/')[1:])
      else:
        url2 = '/'.join(url.split('/')[0:-1]) + '/' + link

      item['link'] = [url2]
      #生成连接 end
      yield item

      #返回多个request
      yield Request(url=url2,callback=self.parse)
    return

爬虫将从start_urls列表中的url开始,将每一个url封装成Request对象,并将parse方法作为回调函数,将返回的Response作为参数传入,response即返回的响应,其中包含了headers和body,headers即响应的头部信息,body即响应的正文信息(html静态页面或json\xml等。。)

在parse方法中即可以利用html/xml解析器通过xpath抓取特定节点的数据,存储到items.py中的指定field中

并将解析到的页面中的其他url转成request返回,交给spider,由spider存放到pipeline队列中scheduler的调度,继续抓取下一个页面

 

回到项目主目录,新建doc目录,切到doc目录,doc作为下载的文档存放目录

运行爬虫:

scrapy crawl ScrapyDoc 

启动名为ScrapyDoc的爬虫。。。

开始抓取页面 。。。。。。

 

将从页面中解析的数据保存到item中

scrapy crawl ScrapyDoc -o myfirst.json -t json  

最后items中定义的域中的数据将作为json数据存储到myfirst.json文件中

posted on 2014-07-19 14:11  菜菜鸟向前进  阅读(837)  评论(0编辑  收藏  举报