昨天用python谢了一个简单爬虫,抓取页面图片;

但实际用到的爬虫需要处理很多复杂的环境,也需要更加的智能,重复发明轮子的事情不能干,

再说python向来以爬虫作为其擅长的一个领域,想必有许多成熟的第三方框架,百度后选用了

Scrapy作为平台构建复杂爬虫。

Scarpy的下载安装不必细说,话说当前只支持python2.x版本,很郁闷,下载安装了python2.7。

安装完后,按照《Scrapy Tutorial》Scrapy at a glance两篇帖子作为学习范本。

概念及步骤简要摘录总结如下:

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

  其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构大致如下:
Scrapy Architecture
  Scrapy主要包括了以下组件:

  • 引擎:用来处理整个系统的数据流处理,触发事务。
  • 调度器:用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。
  • 下载器:用于下载网页内容,并将网页内容返回给蜘蛛。
  • 蜘蛛:蜘蛛是主要干活的,用它来制订特定域名或网页的解析规则。
  • 项目管道:负责处理有蜘蛛从网页中抽取的项目,他的主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
  • 下载器中间件:位于Scrapy引擎和下载器之间的钩子框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
  • 蜘蛛中间件:介于Scrapy引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛的响应输入和请求输出。
  • 调度中间件:介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。

  使用Scrapy可以很方便的完成网上数据的采集工作,它为我们完成了大量的工作,而不需要自己费大力气去开发。

主要步骤:

1. 创建一个Scrapy项目
2. 定义提取的Item
3. 编写爬取网站的 spider 并提取 Item
4. 编写 Item Pipeline 来存储提取到的Item(即数据)

1.scrapy startproject bbsdmoz

2.编辑 bbsDmoz 目录中的 items.py 文件,根据需要从bbs网站获取到的数据对item进行建模;

 1 # -*- coding: utf-8 -*-
 2 # Define here the models for your scraped items
 3 # See documentation in:
 4 # http://doc.scrapy.org/en/latest/topics/items.html
 5 from scrapy.item import Item, Field
 6 class BbsDmozItem(Item):
 7     # define the fields for your item here like:
 8     # name = scrapy.Field()
 9     url   = Field()
     forum = Field()
     poster = Field()

12     content = Field()

3.创建一个Spider,保存在 bbsDmoz/spiders,您必须继承 scrapy.Spider 类。

 从网页中提取数据有很多方法。Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。

这里给出XPath表达式的例子及对应的含义:

  • /html/head/title: 选择HTML文档中 <head> 标签内的 <title> 元素
  • /html/head/title/text(): 选择上面提到的 <title> 元素的文字
  • //td: 选择所有的 <td> 元素
  • //div[@class="mine"]: 选择所有具有 class="mine" 属性的 div 元素

Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):

  • xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。
  • css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.
  • extract(): 序列化该节点为unicode字符串并返回list
  • re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。

4.编写spider代码;

Spider代码

  以下为我们的第一个Spider代码,保存在 bbsDmoz/spiders 目录下的 forumSpider.py 文件中:

1 #-*- coding: utf-8 -*-

 2 '''
 3 bbsSpider, Created on Oct, 2014
 4 #version: 1.0
 5 #author: chenqx @http://chenqx.github.com
 6 See more: http://doc.scrapy.org/en/latest/index.html
 7 '''
 8 from scrapy.selector import Selector
 9 from scrapy.http import  Request
 from scrapy.contrib.spiders import CrawlSpider
 from scrapy.contrib.loader import ItemLoader
 from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
 from bbs.items import BbsItem
 class forumSpider(CrawlSpider):
     # name of spiders
     name = 'bbsSpider'
     allow_domain = ['bbs.sjtu.edu.cn']
     start_urls = [ 'https://bbs.sjtu.edu.cn/bbsall' ]
     link_extractor = {
         'page':  SgmlLinkExtractor(allow = '/bbsdoc,board,\w+\.html$'),
         'page_down':  SgmlLinkExtractor(allow = '/bbsdoc,board,\w+,page,\d+\.html$'),
         'content':  SgmlLinkExtractor(allow = '/bbscon,board,\w+,file,M\.\d+\.A\.html$'),
     }
     _x_query = {
         'page_content':    '//pre/text()[2]',
         'poster'    :    '//pre/a/text()',
         'forum'    :    '//center/text()[2]',
     }
   
     def parse(self, response):
         for link in self.link_extractor['page'].extract_links(response):
             yield Request(url = link.url, callback=self.parse_page)
   
     def parse_page(self, response):
         for link in self.link_extractor['page_down'].extract_links(response):
             yield Request(url = link.url, callback=self.parse_page)
     
         for link in self.link_extractor['content'].extract_links(response):
             yield Request(url = link.url, callback=self.parse_content)
     def parse_content(self, response):
         bbsItem_loader = ItemLoader(item=BbsItem(), response = response)
         url = str(response.url)
         bbsItem_loader.add_value('url', url)
         bbsItem_loader.add_xpath('forum', self._x_query['forum'])
         bbsItem_loader.add_xpath('poster', self._x_query['poster'])
         bbsItem_loader.add_xpath('content', self._x_query['page_content'])
         return bbsItem_loader.load_item()

5.编写 ItemPipeline

当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
  每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。
  以下是item pipeline的一些典型应用:

  • 清理HTML数据
  • 验证爬取的数据(检查item包含某些字段)
  • 查重(并丢弃)
  • 将爬取结果保存,如保存到数据库、XML、JSON等文件中

这个例子将spider从bbs收集来的item写入data.xml文件。

1 # -*- coding: utf-8 -*-

 2 # Define your item pipelines here
 3 # Don't forget to add your pipeline to the ITEM_PIPELINES setting
 4 # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
 5 from scrapy import signals
 6 from scrapy import log
 7 from bbsDmoz.items import BbsDmozItem
 8 from twisted.enterprise import adbapi
 9 from scrapy.contrib.exporter import XmlItemExporter
 from dataProcess import dataProcess
 class XmlWritePipeline(object):
     def __init__(self):
         pass
     @classmethod
     def from_crawler(cls, crawler):
         pipeline = cls()
         crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
         crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
         return pipeline
     def spider_opened(self, spider):
         self.file = open('bbsData.xml', 'wb')
         self.expoter = XmlItemExporter(self.file)
         self.expoter.start_exporting()
     def spider_closed(self, spider):
         self.expoter.finish_exporting()
         self.file.close()
         # process the crawled data, define and call dataProcess function
         # dataProcess('bbsData.xml', 'text.txt')
     def process_item(self, item, spider):
         self.expoter.export_item(item)
         return item

6.编辑setting.py,关联spider与ItemPipeline

1 # -*- coding: utf-8 -*-

 2 # Scrapy settings for bbs project
 3 # For simplicity, this file contains only the most important settings by
 4 # default. All the other settings are documented here:
 5 # http://doc.scrapy.org/en/latest/topics/settings.html
 6 BOT_NAME = 'bbsDomz'
 7 CONCURRENT_REQUESTS = 200
 8 LOG_LEVEL = 'INFO'
 9 COOKIES_ENABLED = True
 RETRY_ENABLED = True
 SPIDER_MODULES = ['bbsDomz.spiders']
 NEWSPIDER_MODULE = 'bbsDomz.spiders'
 # JOBDIR = 'jobdir'
 ITEM_PIPELINES = {
     'bbsDomz.pipelines.XmlWritePipeline': 1000,
 }

7.大功告成,运行一下测试一下吧。

进入项目的根目录bbsDomz/下,执行下列命令启动spider:

scrapy crawl bbsSpider

可以看到命令窗口飞速删除bbs的内容,当然是u1234类似的编码,data.xml文件在不断变大,用sublime可以看到其中的汉字内容。

ctrl+c可以中断运行,很奇怪,一中断后,xml文件读不出来了。

用Scrapy写一个爬虫的更多相关文章

  1. 使用Scrapy创建一个爬虫

    使用Scrapy创建一个爬虫 创建项目 您可以使用下面的命令来创建 Scrapy 项目: scrapy startproject 项目名称 例:scrapy startproject scrapy_p ...

  2. 用Node+wechaty写一个爬虫脚本每天定时给女(男)朋友发微信暖心话

    wechatBot 微信每日说,每日自动发送微信消息给你心爱的人 项目介绍 灵感来源 在掘金看到了一篇<用Node + EJS写一个爬虫脚本每天定时女朋友发一封暖心邮件>后, 在评论区偶然 ...

  3. Python:Scrapy(二) 实例分析与总结、写一个爬虫的一般步骤

    学习自:Scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250 - 知乎 Python Scrapy 爬虫框架实例(一) - Blue·Sky - 博客园 1.声明Item 爬虫爬取的目标是从非 ...

  4. 用python写一个爬虫——爬取性感小姐姐

    忍着鼻血写代码 今天写一个简单的网上爬虫,爬取一个叫妹子图的网站里面所有妹子的图片. 然后试着先爬取了三页,大概有七百多张图片吧!各个诱人的很,有兴趣的同学可以一起来爬一下,大佬级程序员勿喷,简单爬虫 ...

  5. 使用scrapy写好爬虫进行工作的时候,遇到错误及解决方法

    如图中所标出的,提示参数的问题 解决办法: spider目录下的 爬虫文件内容做些更改: 出现报错的文件内容: from scrapy.spiderfrom scrapy.selector impor ...

  6. 自己写一个爬虫 copider

    copider 模仿scrapy的一些写法,当然我这个是单进程的,不是异步的 1.目录 copider/copider.py #coding=utf-8 ''' Created on 2015年10月 ...

  7. 用 Python + itchat 写一个爬虫脚本每天定时给女朋友发微信暖心话

    https://github.com/sfyc23/EverydayWechat.git

  8. python scrapy 入门,10分钟完成一个爬虫

    在TensorFlow热起来之前,很多人学习python的原因是因为想写爬虫.的确,有着丰富第三方库的python很适合干这种工作. Scrapy是一个易学易用的爬虫框架,尽管因为互联网多变的复杂性仍 ...

  9. scrapy 的一个例子

    1.目标: scrapy 是一个爬虫构架,现用一个简单的例子来讲解,scrapy 的使用步骤 2.创建一个scrapy的项目: 创建一个叫firstSpider的项目,命令如下: scrapy sta ...

随机推荐

  1. 替换IMG

    <?php $str = '<img src="http://img01.feiniu.com/images/show/detail/image/20141031/9b3bbc3 ...

  2. wsdl文件结构分析

    WSDL (Web Services Description Language,Web服务描述语言)是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务 ...

  3. 解决Wamp 开启vhost localhost 提示 403 Forbbiden 的问题!

    非常奇怪的一个问题.我曾经从来都没有这样过!訪问 http://localhost/ 提示  403 Forbbiden. 我之前的设置一直都是这种: httpd.conf <Directory ...

  4. css布局&初始化&基准样式

    学习css布局比较好的网站 学习css布局 1.css设置模块 typography(字体) colour(颜色) link(链接) forms(表单) layout(布局) navigation(导 ...

  5. 重学《C#高级编程》(序)

    小生码农一枚,以前只是看别人写博客,从来没有想过要自己写博文,突然之间“脑抽”想自己也写点什么,遂在博客园开通这个博客. 简单介绍下自己吧,本人90后,父母对我没有大的想法,只是希望我平安成长,多学习 ...

  6. NET下三种缓存机制(Winform里面的缓存使用 )

    原文(http://www.cnblogs.com/wuhuacong/p/3526335.html)非常感谢伍华聪作者的分享! 缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度 ...

  7. 使用angularjs中ng-repeat的$even与$odd属性时的注意事项

    JavaScript中数组的索引是从0开始的,因此我们再取奇偶的时候需要用!$even和!$odd来将$even和$odd的布尔值反转 下面给出一个实例: 使用$odd和$even来制作一个红蓝相间的 ...

  8. poj1418 Viva Confetti 判断圆是否可见

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Viva Confetti Time Limit: 1000MS   Memory ...

  9. EC2.0开启多规格后,编辑无法获取规格数据

    我们其实一共碰到2个问题, 1. 一个是弹出了货品编辑画面,但是货品的明细没有2.有货品明细但是货品明细各个字段都是空的, 上面2种情况数据库都是有值的. 第一个问题解决方案: 修改html中的JS ...

  10. 很强的PHP图片处理类

    /*** 基本图片处理,用于完成图片缩入,水印添加* 当水印图超过目标图片尺寸时,水印图能自动适应目标图片而缩小* 水印图可以设置跟背景的合并度** Copyright(c) 2005 by ustb ...