Scrapy笔记03- Spider详解
Scrapy笔记03- Spider详解
Spider是爬虫框架的核心,爬取流程如下:
- 先初始化请求URL列表,并指定下载后处理response的回调函数。初次请求URL通过
start_urls指定,调用start_requests()产生Request对象,然后注册parse方法作为回调 - 在parse回调中解析response并返回字典,
Item对象,Request对象或它们的迭代对象。Request对象还会包含回调函数,之后Scrapy下载完后会被这里注册的回调函数处理。 - 在回调函数里面,你通过使用选择器(同样可以使用BeautifulSoup,lxml或其他工具)解析页面内容,并生成解析后的结果Item。
- 最后返回的这些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详解的更多相关文章
- expect学习笔记及实例详解【转】
1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...
- 机器学习03 /jieba详解
机器学习03 /jieba详解 目录 机器学习03 /jieba详解 1.引言 2.分词 2.1.jieba.cut && jieba.cut_for_search 2.2.jieba ...
- Scrapy的Item_loader机制详解
一.ItemLoader与Item的区别 ItemLoader是负责数据的收集.处理.填充,item仅仅是承载了数据本身 数据的收集.处理.填充归功于item loader中两个重要组件: 输入处理i ...
- Hive笔记--sql语法详解及JavaAPI
Hive SQL 语法详解:http://blog.csdn.net/hguisu/article/details/7256833Hive SQL 学习笔记(常用):http://blog.sina. ...
- 算法笔记--sg函数详解及其模板
算法笔记 参考资料:https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html sg函数大神详解:http://blog.csdn.net/l ...
- Android笔记——四大组件详解与总结
android四大组件分别为activity.service.content provider.broadcast receiver. ------------------------------- ...
- Struts2学习笔记(二)——配置详解
1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin. ...
- Struts2学习笔记二 配置详解
Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的name ...
- Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解
前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY <源路径> .. ...
- vue.js学习笔记(二)——vue-router详解
vue-router详解 原文链接:www.jianshu.com 一.前言 要学习vue-router就要先知道这里的路由是什么?为什么我们不能像原来一样直接用<a></a> ...
随机推荐
- Python 遍历目录下的子目录和文件
import os A: 遍历目录下的子目录和文件 for root,dirs ,files in os.walk(path) root:要访问的路径名 dirs:遍历目录下的子目录 files:遍历 ...
- 说一说switch关键字的奥秘
Switch语法 switch作为Java内置关键字,却在项目中真正使用的比较少.关于switch,还是有那么一些奥秘的. 要什么switch,我有if-else 确实,项目中使用switch比较少的 ...
- Base64和本地以及在线图片互转
package com.ruoyi.common.utils; import java.io.ByteArrayOutputStream; import java.io.FileInputStream ...
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- keyword:react native bridge
js engine native react native bridge https://cn.bing.com/images/search?view=detailV2&id=AAF39636 ...
- WPF 高级篇 MVVM 附加属性
原文:WPF 高级篇 MVVM 附加属性 WPF 特性之一 附加属性 在本文里实现文本框内容的验证 public class TextBoxHelper:DependencyObject { publ ...
- Sqlserver MERGE 的基础用法
版权声明:本文为CSDN博主「暮雪寒寒」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/qq_2762801 ...
- 我是如何一步步编码完成万仓网ERP系统的(六)产品库设计 2.百度Ueditor编辑器
https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...
- ELK + kafka 分布式日志解决方案
概述 本文介绍使用ELK(elasticsearch.logstash.kibana) + kafka来搭建一个日志系统.主要演示使用spring aop进行日志收集,然后通过kafka将日志发送给l ...
- Android 自定义ListView动态加载数据
我们都知道网络取数据是耗时操作,如果我们一次性请求所有数据,假如数据量不多那还可以接受,但是如果数据量特别多,那么带来的后果就是用户的愤怒(用户是很没有耐心的),所以这时候我们就需要动态的加载数据,分 ...