Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
Scrapy 0.24 文档
您可以使用pip来安装Scrapy(推荐使用pip来安装Python package). 使用pip安装: pip install Scrapy
Scrapy爬虫支持多种信息提取的方法: Beautiful Soup Lxml re XPath Selector CSS Selector
Item Pipeline
Feed exports
Windows下可以通过官方文档进行操作。因为我用的是Linux 嘻嘻
简单示例:
1.步骤一:创建一个工程和Spider模板 2.步骤二:编写Spider 3.步骤三:编写Item Pipeline 4.步骤四:优化配置Settings.py
创建项目 在开始爬取之前,您必须创建一个新的Scrapy项目。 进入您打算存储代码的目录中,运行下列命令:
scrapy startproject zimuku 终端显示: You can start your first spider with: cd zimuku scrapy genspider example example.com
进入到工程目录: cd zimuku 我们来看一下目录结构:
. ├── scrapy.cfg #项目的配置文件 └── zimuku #外层目录 ├── __init__.py #初始化脚本 ├── items.py #Items代码模板,继承类自scrapy.Item ├── middlewares.py #Middlewares代码模板(继承类) ├── pipelines.py #Pipelines代码模板(继承类) ├── __pycache__ #Python缓存文件。 ├── settings.py #Scrapy爬虫的配置文件 └── spiders #Spiders代码模板目录 我们写爬虫的地方 ├── __init__.py └── __pycache__ 4 directories, 7 files用命令行创建第一个Spider
爬虫(Spider) Spider是用户编写用于从单个网站(或者一些网站)爬取数据的类。 其包含了一个用于下载的初始URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成 item 的方法。
$ scrapy genspider demo zimuku.net Created spider 'demo' using template 'basic' in module: zimuku.spiders.demo
我们来打开看看scrapy为我们自动生成了那些内容:
$ cat spiders/demo.py # -*- coding: utf-8 -*- import scrapy class DemoSpider(scrapy.Spider):#必须继承 scrapy.Spider 类 name = 'demo' #用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。 allowed_domains = ['zimuku.net'] # start_urls = ['http://zimuku.net/'] # 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。 def parse(self, response): #parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。 pass剩下的事情就是需要我们在此基础上对此框架进行定制,完成自己想要做得事情。
编写Spider 着手定制我们的爬虫吧: 看一下详细的注释
$ cat spiders/demo.py # -*- coding: utf-8 -*- import scrapy # 将我们需要爬取的项目引入进来 from zimuku.items import ZimukuItem class DemoSpider(scrapy.Spider): # 蜘蛛侠名称 name = "demo" # 规定爬虫爬去网页的域名 allowed_domains = ["zimuku.net"] # 开始爬取的url链接 start_urls = ['http://zimuku.net/'] def parse(self, response): # 简单示例,我们就先只爬取第一个字幕的名字 # xpath提取到的是:/html/body/div[2]/div/div/div[2]/table/tbody/tr[1]/td[1]/a/b/text() name = response.xpath('//b//text()').extract()[1] # 建立一个items字典,保存我们爬取道德内容,并返回给pipline处理 items = {} items['第一个']= name return items 关于XPATH,文档http://www.runoob.com/xpath/xpath-syntax.html此处有基本语法,只要能根据基本语法从网页中提取信息就可以。比如下列操作:response.xpath('//b//text()').extract()[1]
在所有属于b的子元素的中的第一个text文本传递给name,/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。 /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
为了配合XPath,Scrapy除了提供了 Selector 之外,还提供了方法来避免每次从response中提取数据时生成selector的麻烦。 Selector有四个基本的方法(点击相应的方法可以看到详细的API文档): 1`xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。 2`css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表. 3`extract(): 序列化该节点为unicode字符串并返回list。 4`re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。
选取节点 XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式:
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
步骤三:编写Item Pipeline 首先我们编写itmes.py来定义这个爬虫框架需要爬哪些内容:
Item ---保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。
类似在ORM中做的一样,您可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个Item。
原框架自动生成的items.py代码如下:
$ cat items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # http://doc.scrapy.org/en/latest/topics/items.html import scrapy class ZimukuItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() pass 我们根据自身需求修改如下: $ cat items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # http://doc.scrapy.org/en/latest/topics/items.html import scrapy class ZimukuItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() subname = scrapy.Field() # 字母的名字 编写 piplines.py来处理spider爬到的内容:原框架自动生成代码如下:
$ cat pipelines.py # -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html class ZimukuPipeline(object): def process_item(self, item, spider): return item 我们现在需要做得就是,简单的将它输出,修改如下: $ cat pipelines.py # -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html class ZimukuPipeline(object): def process_item(self, item, spider): # 将第一个字幕爬取出来输出 print(item) return item步骤四:优化配置Settings.py
原框架自动生成的代码如下:
$ cat settings.py # -*- coding: utf-8 -*- # Scrapy settings for zimuku project # # For simplicity, this file contains only settings considered important or # commonly used. You can find more settings consulting the documentation: # # http://doc.scrapy.org/en/latest/topics/settings.html # http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html BOT_NAME = 'zimuku' SPIDER_MODULES = ['zimuku.spiders'] NEWSPIDER_MODULE = 'zimuku.spiders' ......我们修改如下: # -*- coding: utf-8 -*- # Scrapy settings for zimuku project # # For simplicity, this file contains only settings considered important or # commonly used. You can find more settings consulting the documentation: # # http://doc.scrapy.org/en/latest/topics/settings.html # http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html BOT_NAME = 'zimuku' SPIDER_MODULES = ['zimuku.spiders'] NEWSPIDER_MODULE = 'zimuku.spiders' #通过配置来告诉Scrapy明白是谁来处理结果 ITEM_PIPELINES={'zimuku.pipelines.ZimukuPipeline':300,} 找到ITEM_PIPELINES 选项,把我们pipeline的路径配置进去,后面的数字表示的是pipeline的执行顺序.后面的执行顺序一般在0-1000之间。我们可以写多个pipeline用来过滤数据。
进入项目的根目录,执行下列命令启动spider:
$ scrapy crawl demo crawl demo 启动用于爬取 demo 的spider 2017-08-05 10:56:05 [scrapy.core.scraper] DEBUG: Scraped from <200 http://www.zimuku.net/> {'第一个': '权力的游戏 第七季(第3集-中英双语字幕-衣柜字幕组)Game.of.Thrones.S07E03.The.Queens.Justice.1080p.AMZN.WEB-DL.DD+5.1.H.264-GoT.rar'}