初识 Scrapy
Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取(更确切来说, 网络抓取)所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services)或者通用的网络爬虫。
Scrapy 环境搭建
1. 安装 Python 3.6,本文使用 Python 3.6,且在 PATH 中设置好环境变量。推荐使用Anaconda3 (https://www.anaconda.com/download/)
2. 安装 Scrapy-1.5.1,通过 pip 安装 Scrapy:pip install Scrapy
3. 可能还需的包,包括涉及数据库存储操作的pymssql (适用于sql server):pip install pymssql
Scrapy 项目创建
打开命令行窗口,新建一个 scrapy 工程:
scrapy startproject SpiderProjectName(项目名称)
这个命令会在当前目录(根据需求设置)下创建一个新目录 SpiderProjectName,这就是此爬虫的项目名称。
成功创建爬虫项目文件结构后,进入目录,使用命令: tree /f 查看文件层级的结构关系
这些文件主要是:
scrapy.cfg: 项目配置文件
SpiderProjectName/: 项目python模块, 代码将从这里导入
SpiderProjectName/items.py: 项目items文件
SpiderProjectName/pipelines.py: 项目管道文件
SpiderProjectName/settings.py: 项目配置文件
SpiderProjectName/spiders: 放置spider的目录
定义item
编辑 items.py 文件,items 是将要装载抓取的数据的容器,它工作方式像 python 里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。在 items.py 文件里,scrapy 需要我们定义一个容器用于放置爬虫抓取的数据,它通过创建一个scrapy.Item 类来声明,定义它的属性为scrpy.Field 对象,就像是一个对象关系映射(ORM, Object Relational Mapping)。我们通过将需要的 item 模型化,来控制从站点获得的新闻数据,比如我们要获得新闻的标题项、内容项、发表时间、图片链接地址和页面链接地址,则定义这5种属性的域。Scrapy 框架已经定义好了基础的 item,我们自己的 item 只需继承 scrapy.Item 即可。
# 示例
class ClawlerItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 主题名称
title = scrapy.Field()
# 主题种类
category = scrapy.Field()
# 语言
lang = scrapy.Field()
# 返回内容
content = scrapy.Field()
pass
爬虫spider主程序
在spiders文件夹下,新建 SpiderName.py 文件, Scrapy 框架已经帮助我们定义好了基础爬虫,只需要从 scrapy.spider 继承,并重写相应的解析函数 parse 即可。其中会涉及到使用 xPath 获取页面元素路径的操作,xPaht 是 XML 页面路径语言,使用路径表达式来选取 XML 文档中的节点或节点集,节点是通过沿着路径(Path)或者步(Steps)来选取的,html 是 XML 的子集,当然同样适用,有兴趣的读者可以自行查阅相关的 Xpath 文档。
数据存储
编辑 pipelines.py 文件,用于将 items 中的数据存储到数据库或者本地文本等。
# 涉及数据库存储的方式,数据库参数都在settings中设置,更灵活
import pymssql
class ClawlerPipeline(object):
# 定义数据库链接
def __init__(self):
self.connect = pymssql.connect(host=SQLServer_HOST, user=SQLServer_USER, password=SQLServer_PASSWD,
database=SQLServer_DBNAME, port=SQLServer_PORT)
self.cursor = self.connect.cursor()
def process_item(self, item, spider):
try:
sql = "insert into dbo.YB_ALL(ztid,title,category,lang,content,gxrq,demo) values (%s,%s,%s,%s,%s,%s,%s)"
self.cursor.execute(sql,(item['id'],item['title'], item['category'], item['lang'], str(item['content']), timestamp, None))
self.connect.commit()
time.sleep(10)
self.close_spider(spider)
except Exception as error:
get_logger('error.log').info(str(error))
def close_spider(self, spider):
self.connect.close()
# 本地存储方式
# def process_item(self, item, spider):
# with open("test1.txt", 'a', encoding='utf-8') as fw:
# # json.dump(str(item['content']), fw, ensure_ascii=False)
# fw.write(str(item['content']) + '\n')
# util.py工具类中的日志方法也贴出来分享吧
import logging
def get_logger(filename):
logger = logging.getLogger('logger')
logger.setLevel(logging.DEBUG)
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
handler = logging.FileHandler(filename)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
logging.getLogger().addHandler(handler)
return logger
激活 pipeline 管道
编辑 settings.py 文件 中的 ITEM_PIPELINES ,添加如下代码
# DBspiderPipeline 是你定义在Pipeline文件中的类
# 项目名.pipelines.管道类名, 根据你的情况更改
ITEM_PIPELINES = {
'SpiderProjectName.pipelines.DBSpiderPipeline': 300,
}
# 编码
FEED_EXPORT_ENCODING = 'utf-8'
# 数据库声明
SQLServer_HOST = '127.0.0.1'
SQLServer_DBNAME = 'DATA_SAMPLE'
SQLServer_USER = 'sa'
SQLServer_PASSWD = '12345'
SQLServer_PORT = 1433
包括数据库属性,编码等等,都可以在settings.py中设置
运行爬虫
爬虫项目根目录下,执行命令如下:
scrapy crawl SpiderProjectName