【转】 Scrapy研究探索(六)——自动爬取网页之II(CrawlSpider)
2015-10-17 16:20
387 查看
转自/article/1378195.html
在pipelines.py中实现获得数据的过滤以及保存。
但是以上述方法只能爬取start_url列表中的网页,而网络爬虫如google等搜索引擎爬虫实现的就是对整个互联网的爬取,所以在本教程中研究使用scrapy自动实现多网页爬取功能。
在教程(五)(/article/1378196.html)中已经编写继承自spider的类实现爬虫,实现了自动多网页爬取,这里引出CrawlSpider类,使用更简单方式实现自动爬取。
[python] view plaincopy
class scrapy.contrib.spiders.Rule (
link_extractor, callback=None,cb_kwargs=None,follow=None,process_links=None,process_request=None )
callback参数:当link_extractor获取到链接时参数所指定的值作为回调函数。
follow:指定了根据该规则从response提取的链接是否需要跟进。当callback为None,默认值为true。
process_links:主要用来过滤由link_extractor获取到的链接。
process_request:主要用来过滤在rule中提取到的request。
[python] view plaincopy
classscrapy.contrib.linkextractors.sgml.SgmlLinkExtractor(
allow=(),deny=(),allow_domains=(),deny_domains=(),deny_extensions=None,restrict_xpaths=(),tags=('a','area'),attrs=('href'),canonicalize=True,unique=True,process_value=None)
主要参数:
allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
allow_domains:会被提取的链接的domains。
deny_domains:一定不会被提取链接的domains。
restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。
[python] view plaincopy
scrapy shell http://blog.csdn.net/u012150179/article/details/11749017
继续import相关模块:
[python] view plaincopy
fromscrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
现在使用SgmlLinkExtractor查看在当前网页中获得的链接:
[python] view plaincopy
item=SgmlLinkExtractor(allow=('/u012150179/article/details')).extract_links(response)
其中item为包含Link()对象的列表,现在显示其中的text元素(就是获取到的文章链接对应的文章标题):
[python] view plaincopy
for i in item:
print i.text
部分结果截图:
对照网页可以得到此时获取的是当前网页中所有满足allow条件的链接,不仅包含“下一篇”的链接,还有网页侧边栏“阅读排行“、”评论排行“中的文章链接。为了只获得”下一篇“文章链接,这就要进行所有链接的筛选,引入参数restrict_xpaths,继续:
[python] view plaincopy
item= SgmlLinkExtractor(allow=('/u012150179/article/details'),restrict_xpaths=('//li[@class="next_article"]')).extract_links(response)
这是在如上查看结果,便提取出了“下一篇”文章链接。
注意:在shell中并不对提取到的link进行跟进。
在这里不得不提的就是scrapy shell是对调试、验证很有用的交互工具。应该掌握。
在shell中进行了验证后进入写代码阶段。
上码:
[python] view plaincopy
# -*- coding:utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import Selector
from CSDNBlogCrawlSpider.items import CsdnblogcrawlspiderItem
class CSDNBlogCrawlSpider(CrawlSpider):
"""继承自CrawlSpider,实现自动爬取的爬虫。"""
name = "CSDNBlogCrawlSpider"
#设置下载延时
download_delay = 2
allowed_domains = ['blog.csdn.net']
#第一篇文章地址
start_urls = ['http://blog.csdn.net/u012150179/article/details/11749017']
#rules编写法一,官方文档方式
#rules = [
# #提取“下一篇”的链接并**跟进**,若不使用restrict_xpaths参数限制,会将页面中所有
# #符合allow链接全部抓取
# Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),
# restrict_xpaths=('//li[@class="next_article"]')),
# follow=True)
#
# #提取“下一篇”链接并执行**处理**
# #Rule(SgmlLinkExtractor(allow=('/u012150179/article/details')),
# # callback='parse_item',
# # follow=False),
#]
#rules编写法二,更推荐的方式(自己测验,使用法一时经常出现爬到中间就finish情况,并且无错误码)
rules = [
Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),
restrict_xpaths=('//li[@class="next_article"]')),
callback='parse_item',
follow=True)
]
def parse_item(self, response):
#print "parse_item>>>>>>"
item = CsdnblogcrawlspiderItem()
sel = Selector(response)
blog_url = str(response.url)
blog_name = sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()
item['blog_name'] = [n.encode('utf-8') for n in blog_name]
item['blog_url'] = blog_url.encode('utf-8')
yield item
运行:
[python] view plaincopy
scrapy crawl CSDNBlogCrawlSpider
得到的效果如教程(五)一致。
进行到这里,就将本篇文章主题讲述完毕,核心是CrawlSpider,主要方法是rules。
关于scrapy的使用可参见之前文章:
/article/1378195.html
/article/1378196.html
http://blog.csdn.net/u012150179/article/details/34441655
/article/1378199.html
一.目的。
在教程(二)(/article/1378199.html)中使用基于Spider实现了自己的w3cschool_spider,并在items.py中定义了数据结构,在pipelines.py中实现获得数据的过滤以及保存。
但是以上述方法只能爬取start_url列表中的网页,而网络爬虫如google等搜索引擎爬虫实现的就是对整个互联网的爬取,所以在本教程中研究使用scrapy自动实现多网页爬取功能。
在教程(五)(/article/1378196.html)中已经编写继承自spider的类实现爬虫,实现了自动多网页爬取,这里引出CrawlSpider类,使用更简单方式实现自动爬取。
二.热身。
1.CrawlSpider
(1)概念与作用:
它是Spider的派生类,首先在说下Spider,它是所有爬虫的基类,对于它的设计原则是只爬取start_url列表中的网页,而从爬取的网页中获取link并继续爬取的工作CrawlSpider类更适合。(2)使用:
它与Spider类的最大不同是多了一个rules参数,其作用是定义提取动作。在rules中包含一个或多个Rule对象,Rule类与CrawlSpider类都位于scrapy.contrib.spiders模块中。[python] view plaincopy
class scrapy.contrib.spiders.Rule (
link_extractor, callback=None,cb_kwargs=None,follow=None,process_links=None,process_request=None )
其中:
link_extractor为LinkExtractor,用于定义需要提取的链接。callback参数:当link_extractor获取到链接时参数所指定的值作为回调函数。
callback参数使用注意:
当编写爬虫规则时,请避免使用parse作为回调函数。于CrawlSpider使用parse方法来实现其逻辑,如果您覆盖了parse方法,crawlspider将会运行失败。follow:指定了根据该规则从response提取的链接是否需要跟进。当callback为None,默认值为true。
process_links:主要用来过滤由link_extractor获取到的链接。
process_request:主要用来过滤在rule中提取到的request。
2.LinkExtractor
(1)概念:
顾名思义,链接提取器。(2) 作用:
response对象中获取链接,并且该链接会被接下来爬取。(3) 使用:
通过SmglLinkExtractor提取希望获取的链接。[python] view plaincopy
classscrapy.contrib.linkextractors.sgml.SgmlLinkExtractor(
allow=(),deny=(),allow_domains=(),deny_domains=(),deny_extensions=None,restrict_xpaths=(),tags=('a','area'),attrs=('href'),canonicalize=True,unique=True,process_value=None)
主要参数:
allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
allow_domains:会被提取的链接的domains。
deny_domains:一定不会被提取链接的domains。
restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。
三.RUN!
shell中验证
开始编写代码之前,使用scrapyshell查看使用SmglLinkExtractor在网页中获取到的链接:[python] view plaincopy
scrapy shell http://blog.csdn.net/u012150179/article/details/11749017
继续import相关模块:
[python] view plaincopy
fromscrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
现在使用SgmlLinkExtractor查看在当前网页中获得的链接:
[python] view plaincopy
item=SgmlLinkExtractor(allow=('/u012150179/article/details')).extract_links(response)
其中item为包含Link()对象的列表,现在显示其中的text元素(就是获取到的文章链接对应的文章标题):
[python] view plaincopy
for i in item:
print i.text
部分结果截图:
对照网页可以得到此时获取的是当前网页中所有满足allow条件的链接,不仅包含“下一篇”的链接,还有网页侧边栏“阅读排行“、”评论排行“中的文章链接。为了只获得”下一篇“文章链接,这就要进行所有链接的筛选,引入参数restrict_xpaths,继续:
[python] view plaincopy
item= SgmlLinkExtractor(allow=('/u012150179/article/details'),restrict_xpaths=('//li[@class="next_article"]')).extract_links(response)
这是在如上查看结果,便提取出了“下一篇”文章链接。
注意:在shell中并不对提取到的link进行跟进。
在这里不得不提的就是scrapy shell是对调试、验证很有用的交互工具。应该掌握。
在shell中进行了验证后进入写代码阶段。
编写代码
(1)items.py和pipelines.py以及settings.py与之前教程类似,不详细描述。
(2)爬虫编写。
上码:[python] view plaincopy
# -*- coding:utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import Selector
from CSDNBlogCrawlSpider.items import CsdnblogcrawlspiderItem
class CSDNBlogCrawlSpider(CrawlSpider):
"""继承自CrawlSpider,实现自动爬取的爬虫。"""
name = "CSDNBlogCrawlSpider"
#设置下载延时
download_delay = 2
allowed_domains = ['blog.csdn.net']
#第一篇文章地址
start_urls = ['http://blog.csdn.net/u012150179/article/details/11749017']
#rules编写法一,官方文档方式
#rules = [
# #提取“下一篇”的链接并**跟进**,若不使用restrict_xpaths参数限制,会将页面中所有
# #符合allow链接全部抓取
# Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),
# restrict_xpaths=('//li[@class="next_article"]')),
# follow=True)
#
# #提取“下一篇”链接并执行**处理**
# #Rule(SgmlLinkExtractor(allow=('/u012150179/article/details')),
# # callback='parse_item',
# # follow=False),
#]
#rules编写法二,更推荐的方式(自己测验,使用法一时经常出现爬到中间就finish情况,并且无错误码)
rules = [
Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'),
restrict_xpaths=('//li[@class="next_article"]')),
callback='parse_item',
follow=True)
]
def parse_item(self, response):
#print "parse_item>>>>>>"
item = CsdnblogcrawlspiderItem()
sel = Selector(response)
blog_url = str(response.url)
blog_name = sel.xpath('//div[@id="article_details"]/div/h1/span/a/text()').extract()
item['blog_name'] = [n.encode('utf-8') for n in blog_name]
item['blog_url'] = blog_url.encode('utf-8')
yield item
运行:
[python] view plaincopy
scrapy crawl CSDNBlogCrawlSpider
得到的效果如教程(五)一致。
其中指出和教程(五)所编写爬虫方法的差异:
首先,基类CrawlSpider提供了更完善的自动多网页爬取机制,只需要我们配置的就是rules,通过Rule对象实现链接的提取与跟进,恩,对,没了。。。就这样。详细的注释也都在程序中。进行到这里,就将本篇文章主题讲述完毕,核心是CrawlSpider,主要方法是rules。
关于scrapy的使用可参见之前文章:
/article/1378195.html
/article/1378196.html
http://blog.csdn.net/u012150179/article/details/34441655
/article/1378199.html
相关文章推荐
- 【HDOJ】3315 My Brute
- Django1.8特性
- quartz_jobs.xml配置文件样例2--CronTrigger
- maven报错
- Android中bluetooth的架构
- 【HDOJ】2853 Assignment
- C语言基础(四)分支结构、循环结构
- 32SkypeForBusiness2015进阶篇--故障转移节点
- Java基础编程10-各种类型的转换
- c++关键字 mutable
- iOS Core Animation学习总结(2)--实现自定义图层
- scrapy爬虫编写过程中的小技巧
- 总线(BUS)和总线操作
- C语言基础(三)运算符
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Excel 搜索替换 软换行符
- 杭电1002(简单的大数)
- cache 一致性
- 使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。
- Java学习之Hessian通信基础