Scrapy笔记03- Spider详解

Spider是爬虫框架的核心,爬取流程如下:

  1. 先初始化请求URL列表,并指定下载后处理response的回调函数。初次请求URL通过start_urls指定,调用start_requests()产生Request对象,然后注册parse方法作为回调
  2. 在parse回调中解析response并返回字典,Item对象,Request对象或它们的迭代对象。Request对象还会包含回调函数,之后Scrapy下载完后会被这里注册的回调函数处理。
  3. 在回调函数里面,你通过使用选择器(同样可以使用BeautifulSoup,lxml或其他工具)解析页面内容,并生成解析后的结果Item。
  4. 最后返回的这些Item通常会被持久化到数据库中(使用Item Pipeline)或者使用Feed exports将其保存到文件中。

尽管这个流程适合于所有的蜘蛛,但是Scrapy里面为不同的使用目的实现了一些常见的Spider。下面我们把它们列出来。

CrawlSpider

链接爬取蜘蛛,专门为那些爬取有特定规律的链接内容而准备的。 如果你觉得它还不足以适合你的需求,可以先继承它然后覆盖相应的方法,或者自定义Spider也行。

它除了从scrapy.Spider类继承的属性外,还有一个新的属性rules,它是一个Rule对象列表,每个Rule对象定义了某个规则,如果多个Rule匹配一个连接,那么使用第一个,根据定义的顺序。

一个详细的例子:

from coolscrapy.items import HuxiuItem
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor class LinkSpider(CrawlSpider):
name = "link"
allowed_domains = ["huxiu.com"]
start_urls = [
"http://www.huxiu.com/index.php"
] rules = (
# 提取匹配正则式'/group?f=index_group'链接 (但是不能匹配'deny.php')
# 并且会递归爬取(如果没有定义callback,默认follow=True).
Rule(LinkExtractor(allow=('/group?f=index_group', ), deny=('deny\.php', ))),
# 提取匹配'/article/\d+/\d+.html'的链接,并使用parse_item来解析它们下载后的内容,不递归
Rule(LinkExtractor(allow=('/article/\d+/\d+\.html', )), callback='parse_item'),
) def parse_item(self, response):
self.logger.info('Hi, this is an item page! %s', response.url)
detail = response.xpath('//div[@class="article-wrap"]')
item = HuxiuItem()
item['title'] = detail.xpath('h1/text()')[0].extract()
item['link'] = response.url
item['posttime'] = detail.xpath(
'div[@class="article-author"]/span[@class="article-time"]/text()')[0].extract()
print(item['title'],item['link'],item['posttime'])
yield item

XMLFeedSpider

XML订阅蜘蛛,用来爬取XML形式的订阅内容,通过某个指定的节点来遍历。 可使用iternodes, xml, 和html三种形式的迭代器,不过当内容比较多的时候推荐使用iternodes, 默认也是它,可以节省内存提升性能,不需要将整个DOM加载到内存中再解析。而使用html可以处理XML有格式错误的内容。 处理XML的时候最好先Removing namespaces

接下来我通过爬取我的博客订阅XML来展示它的使用方法。

from coolscrapy.items import BlogItem
import scrapy
from scrapy.spiders import XMLFeedSpider class XMLSpider(XMLFeedSpider):
name = "xml"
namespaces = [('atom', 'http://www.w3.org/2005/Atom')]
allowed_domains = ["github.io"]
start_urls = [
"http://www.pycoding.com/atom.xml"
]
iterator = 'xml' # 缺省的iternodes,貌似对于有namespace的xml不行
itertag = 'atom:entry' def parse_node(self, response, node):
# self.logger.info('Hi, this is a <%s> node!', self.itertag)
item = BlogItem()
item['title'] = node.xpath('atom:title/text()')[0].extract()
item['link'] = node.xpath('atom:link/@href')[0].extract()
item['id'] = node.xpath('atom:id/text()')[0].extract()
item['published'] = node.xpath('atom:published/text()')[0].extract()
item['updated'] = node.xpath('atom:updated/text()')[0].extract()
self.logger.info('|'.join([item['title'],item['link'],item['id'],item['published']]))
return item

CSVFeedSpider

这个跟上面的XMLFeedSpider很类似,区别在于它会一行一行的迭代,而不是一个节点一个节点的迭代。 每次迭代行的时候会调用parse_row()方法。

from coolscrapy.items import BlogItem
from scrapy.spiders import CSVFeedSpider class CSVSpider(CSVFeedSpider):
name = "csv"
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/feed.csv']
delimiter = ';'
quotechar = "'"
headers = ['id', 'name', 'description'] def parse_row(self, response, row):
self.logger.info('Hi, this is a row!: %r', row)
item = BlogItem()
item['id'] = row['id']
item['name'] = row['name']
return item

SitemapSpider

站点地图蜘蛛,允许你使用Sitemaps发现URL后爬取整个站点。 还支持嵌套的站点地图以及从robots.txt中发现站点URL

 

Scrapy笔记03- Spider详解的更多相关文章

  1. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...

  2. 机器学习03 /jieba详解

    机器学习03 /jieba详解 目录 机器学习03 /jieba详解 1.引言 2.分词 2.1.jieba.cut && jieba.cut_for_search 2.2.jieba ...

  3. Scrapy的Item_loader机制详解

    一.ItemLoader与Item的区别 ItemLoader是负责数据的收集.处理.填充,item仅仅是承载了数据本身 数据的收集.处理.填充归功于item loader中两个重要组件: 输入处理i ...

  4. Hive笔记--sql语法详解及JavaAPI

    Hive SQL 语法详解:http://blog.csdn.net/hguisu/article/details/7256833Hive SQL 学习笔记(常用):http://blog.sina. ...

  5. 算法笔记--sg函数详解及其模板

    算法笔记 参考资料:https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html sg函数大神详解:http://blog.csdn.net/l ...

  6. Android笔记——四大组件详解与总结

     android四大组件分别为activity.service.content provider.broadcast receiver. ------------------------------- ...

  7. Struts2学习笔记(二)——配置详解

    1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin. ...

  8. Struts2学习笔记二 配置详解

    Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的name ...

  9. Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解

    前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY  <源路径> .. ...

  10. vue.js学习笔记(二)——vue-router详解

    vue-router详解 原文链接:www.jianshu.com 一.前言 要学习vue-router就要先知道这里的路由是什么?为什么我们不能像原来一样直接用<a></a> ...

随机推荐

  1. 熟悉使用ssm框架完成项目

    羡慕那些一些博客就能写好多的人,总是能写的长篇大论的,而我就是简短的而且还伴随着语句不通顺等等,只写一点点,归根结底还是自己懒得写! 1.首先了解框架内容,拿到源码,先看配置文件 2.然后修改数据库建 ...

  2. Docker下构建centos7容器无法使用systemctl命令的解决办法

    最近在使用docker 构建centos7 容器时,发现无法使用systemctl 命令.后来万能的百度解决了问题,随记之以备后用. 解决办法: docker run --privileged -it ...

  3. Mysql 生成不重复的随机数字

    在网上查找Mysql 生成不重复的随机数字 ,竟然没找到合适的例子. 其实思路很简单,利用MySQL现有的函数,然后进行加工处理,达到预期的结果.可以用到的MySQL函数为rand() ,以及 rou ...

  4. 在Azure DevOps Server (TFS)中实现VUE项目的自动打包

    概述 Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的渐进式框架.由于它在数据绑定.页面展示和使用简单方面有很大的优势,逐渐被越来越多的前端开发团队使用.本文 ...

  5. 启动apache,将debug日志输出在console窗口

    sudo apachectl -k start -e DEBUG 点个广告吧亲:

  6. 论文阅读: Direct Monocular Odometry Using Points and Lines

    Direct Monocular Odometry Using Points and Lines Abstract 大多数VO都用点: 特征匹配 / 基于像素intensity的直接法关联. 我们做了 ...

  7. Pandas中查看列中数据的种类及个数

    Pandas中查看列中数据的种类及个数 读取数据 import pandas as pd import numpy as np filepath = 'your_file_path.csv' data ...

  8. RabbitMQ的构架

    初识rabbitMQ RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现. AMQP :Advanced Message Queue,高级消息队列协议.它是应用层协议的一个开放 ...

  9. XMLHttpRequest原生方法

    时间久了,在工作中会有很多方法和见解. 随着时间的推移,慢慢的写的代码越来越多,封装分方法也越来越多,为的是方便后续工作,加快开发效率! 与此同时,我们会相应的去找一些插件,来代替我们在开发过程中执行 ...

  10. linux内核debug的一种方式:procfs

    #include <linux/module.h> #include <linux/compat.h> #include <linux/types.h> #incl ...