Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。(百度百科的描述)
安装过程见CentOS7下安装Scrapy,基于Python2.7.5版本。
scrapy startproject FinancialSpider
可使用scrapy -h 获取使用帮助。
生成的项目目录结构如下:
FinancialSpider/
FinancialSpider/
spiders/
__init__.py
__init__.py
items.py
pipelines.py
settings.py
scrapy.cfg
主要有几个部分:
import scrapy
class FinancialspiderItem(scrapy.Item):
# define the fields for your item here like:
html_content = scrapy.Field()
(注:本项目基于scrapy1.2.0,不同版本代码可能有差异,后文不再叙述)
由于需要抓取整个网页内容,故定义一个Field对象。
import codecs
class FinancialspiderPipeline(object):
def __init__(self):
self.file = codecs.open('financial_file1', mode='ab', encoding='utf-8')
def process_item(self, item, spider):
content = item['html_content']
#self.file.write(content.decode("unicode_escape"))
self.file.write(content)
return item
初始化时以追加的模式打开数据将要保存的文件。
每个Pipeline组件需要实现process_item方法,参数item为抓取的Item对象,spider为抓取item的Spider对象。方法可返回Item对象,或者raise DropItem Exception等。
在此,将Item中的值写入保存文件。
Settings提供了key-value映射的全局命名空间,代码中可以获取配置的值。settings.py是scrapy项目的标准配置文件,也可通过命令行选项,spider类中等方式定义。
ROBOTSTXT_OBEY = False
是否遵循robots.txt协议
COOKIES_ENABLED = False
防止了网站使用cookies识别爬虫
ITEM_PIPELINES = {
'FinancialSpider.pipelines.FinancialspiderPipeline': 300,
}
激活自定义的Pipeline组件
DOWNLOAD_TIMEOUT = 15
减少下载超时时间,以便越过太慢的连接请求,快速进行下一网页的抓取
DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'
默认的重复请求检测过滤,可自己实现RFPDupeFilter的子类,覆写其request_fingerprint方法。
DEPTH_PRIORITY = 1
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'
scrapy默认使用LIFO队列存储请求,即以深度优先方式进行抓取。通过以上设置,以广度优先方式进行抓取。
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.selector import Selector
from FinancialSpider.items import FinancialspiderItem
class FinancialSpider(CrawlSpider):
"""继承自CrawlSpider,实现自动爬取的爬虫。"""
name = 'FinancialSpider'
download_delay = 1
# make scrapy crawl any site without allowed domains restriction
#allowed_domains = ['eastmoney.com']
start_urls = ['http://www.eastmoney.com']
rules = [
Rule(LinkExtractor(allow=(),
restrict_xpaths=('//a[@href]')),
callback='parse_item',
follow=True)
]
def parse_start_url(self, response):
item = FinancialspiderItem()
sel = Selector(response)
content_list = sel.xpath('/html').extract()
content = content_list[0]
item['html_content'] = content + u'\n'
return item
def parse_item(self, response):
item = FinancialspiderItem()
sel = Selector(response)
content_list = sel.xpath('/html').extract()
if len(content_list) > 0:
content = content_list[0]
# print type(content_list)
# print "content_len: "
# print len(content_list)
#print type(content)
#item['html_content'] = [n.encode('utf-8') for n in content]
item['html_content'] = content + u'\n'
yield item
在此设置了download_delay为1秒,以免访问频繁被服务器禁止访问,经验证,已满足需求。
CrawlSpider是Spider的子类,提供了通过定义一系列rule来跟踪链接的更便利的机制。由于需要递归爬取网页,CrawlSpider更加方便。
Rule对象定义了爬取网站的特定行为。其第一个参数Link Extractor object描述了从每个爬取网页中提取链接的方式,callback参数用于处理Link Extractor 提取的链接。
parse_start_url方法为CrawlSpider特有的方法,用于处理start_urls指定页面的response。
在parse_item方法中使用Selector并通过XPath实现数据的提取,在此提取的是html标签中的所有内容。
使用user agent池,避免服务器禁止访问。具体代码和说明参见 Scrapy研究探索(七)——如何防止被ban之策略大集合
在shell中,进入第一个FinancialSpider目录,使用以下命令启动爬虫
scrapy crawl FinancialSpider --logfile=log --loglevel=WARNING
可以看到,保存文件生成在下级目录下,内容不断增大。
可在Shell中通过按下两次ctrl-c停止爬虫。
若爬虫在后台运行,可执行两次下列代码,实现同样功能。
kill -2 $(ps -ef | grep FinancialSpider | awk '{print $2}')