Scrapy爬虫框架
安装 : pip install scrapy
测试成功 : scrapy -h
Scrapy爬虫框架“5+2”结构:
Scrapy主要组件:
- 引擎(Engine)
用来控制所有模块之间的数据流, 触发事务(框架核心)
- 下载器(Downloader)
用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
- 爬虫(Spiders)
解析Downloader返回的响应(Response);产生爬取项(scrapy item);产生额外的爬取请求(Request)
- 项目管道(Item Pipeline)
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送 到项目管道,并经过几个特定的次序(流水线)处理数据。
- 下载器中间件(Downloader Middlewares)
位于引擎和下载器之间的框架,主要是处理引擎与下载器之间的请求及响应,丢弃、修改、新增。
- 调度中间件(Scheduler Middewares)
- 爬虫中间件(Spider Middlewares)
介于引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
- 调度器(Scheduler)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
Request vs Scrapy
Request | Scrapy |
页面级爬虫 | 网站级爬虫 |
功能库 | 框架 |
并发性考虑不足 | 并发性好,性能高 |
重点在于页面下载 | 重点在于爬虫结构 |
定制灵活 | 一般定制灵活,深度定制困难 |
上手简单 | 入门稍难 |
Scrapy运行流程:
- 引擎从调度器中取出一个链接(URL)用于接下来的抓取
- 引擎把URL封装成一个请求(Request)传给下载器
- 下载器把资源下载下来,并封装成应答包(Response)
- 爬虫解析Response
- 解析出实体(Item),则交给实体管道进行进一步的处理
- 解析出的是链接(URL),则把URL交给调度器等待抓取
Scrapy使用形式:命令行
查看所有命令
scrapy -h
查看帮助信息
scapy --help
查看版本信息
scrapy version #Scrapy 1.1.2
scrapy version -v
Scrapy : 1.5.0
lxml : 4.1.1.0
libxml2 : 2.9.5
cssselect : 1.0.3
parsel : 1.3.1
w3lib : 1.18.0
Twisted : 17.9.0
Python : 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)]
pyOpenSSL : 17.5.0 (OpenSSL 1.1.0g 2 Nov 2017)
cryptography : 2.1.4
Platform : Windows-10-10.0.14393
- 建立工程和Spider模板
- 编写Spider
- 编写Pipeline
- 配置优化
Scrapy爬虫的数据类型:
- Request类:
1、cless scrapy.http.Request();
2、request对象表示一个HTTP请求;
3、由Spider生成,由Downloader执行
- Response类
1、cless scrapy.http.Response();
2、response对象表示一个HTTP请求;
3、由Downloader生成,由Spider处理
- Item类
1、cless scrapy.item.Item();
2、item对象表示从HTML页面中提取的信息内容;
3、由Spider生成,由Item Pipeline处理
4、可以按照字典类型操作;
Scrapy爬虫支持的HTML信息提取方法:
- Beautiful Soup
- lxml
- re
- XPath Selector
- CSS Selector
>>>response.css('xxx')
yield关键字的使用:
Iterables
当你创建一个list,你可以一个一个的获取,这种列表就称为迭代:
mylist = [1, 2, 3]
for i in mylist:
print(i) #1 2 3
mylist 是一个迭代器. 当你理解它为一个list,它便是可迭代的:
mylist =
[x*x for x in range(3)]
for i in mylist:
print(i) #0 1 4
任何可以用 for ..in.. 来迭代读取的都是迭代容器,如lists,strings,files.需要存储所有的值,其中很多值没有必要每次都保持在内存中。
Generators
Generators(生成器)是可迭代的,每次只能迭代一次,因为不是所有的迭代器都被一直存储在内存中的:
mygenerator =
(x*x for x in range(3))
for i in mygenerator:
print(i) #0 1 4
Yield
Yield返回一个生成器,例如:
def createGenerator():
mylist = range(3)
for i in mylist:
yield i*i
mygenerator = createGenerator() # 创建generator
print(mygenerator) # mygenerator 是一个对象! 输出<generator object createGenerator at 0xb7555c34>
for i in mygenerator:
print(i) #0 1 4
当调用creatGenerator
的时候,这个函数中的代码并没有真正运行。它仅仅返回一个生成器对象,
代码会在每次for使用生成器的时候跑起来。
练习案例:
入门篇:美剧天堂前100最新(http://www.meijutt.com/new100.html)
1、创建工程
scrapy startproject movie
2、创建爬虫程序
cd movie
scrapy genspider meiju meijutt.com #生成meiju.py----
3、自动创建目录及文件
4、文件说明:
- _init_.py 初始化脚本
- scrapy.cfg 项目的配置信息,主要为Scrapy命令行工具提供一个基础的配置信息。(真正爬虫相关的配置信息在settings.py文件中)
- items.py 设置数据存储模板,用于结构化数据,如:Django的Model
- pipelines.py Pipelines代码模板(继承类),数据处理行为,如:一般结构化的数据持久化
- middlewares.py Middlewares代码模板(继承类)
- settings.py Scrapy的配置文件,如:递归的层数、并发数,延迟下载等
- spiders 爬虫目录,如:创建文件,编写爬虫规则
注意:一般创建爬虫文件时,以网站域名命名。
5、设置数据存储模板
items.py
import scrapy
class MovieItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field()
6、编写爬虫
meiju.py
# -*- coding: utf-8 -*-
import scrapy
from movie.items import MovieItem
class MeijuSpider(scrapy.Spider): #继承scrapy.spider
name = "meiju"
allowed_domains = [ "meijutt.com" ] #最开始用户提交给命令行的域名,只能爬取该域名以下的内容
start_urls = [ 'http://www.meijutt.com/new100.html' ] #要爬取的初始页面
def parse(self, response): #解析页面方法:用于处理响应,解析内容形成字典,发现新的URL爬取请求
movies = response.xpath( '//ul[@class="top-list fn-clear"]/li' )
for each_movie in movies:
item = MovieItem()
item[ 'name' ] = each_movie.xpath( './h5/a/@title' ).extract()[0]
yield item
7、设置配置文件
settings.py增加如下内容
ITEM_PIPELINES = { 'movie.pipelines.MoviePipeline' :100}
8、编写数据处理脚本
pipelines.py
class MoviePipeline( object ):
def process_item(self, item, spider):
with open( "my_meiju.txt" , 'a' ) as fp:
fp.write(item[ 'name' ].encode( "utf8" ) + '\n' )
9、执行爬虫
cd movie
scrapy crawl meiju --nolog
10、结果显示