以前我们写爬虫,要导入和操作不同的模块,比如requests模块、gevent库、pymysql模块等。而在Scrapy里,你不需要这么做,因为很多爬虫需要涉及的功能,比如麻烦的异步,在Scrapy框架都自动实现了
我们之前编写爬虫的方式,相当于在一个个地在拼零件,拼成一辆能跑的车。而Scrapy框架则是已经造好的、现成的车,我们只要踩下它的油门,它就能跑起来。这样便节省了我们开发项目的时间
Scrapy的结构
Scheduler
(调度器)部门主要负责处理引擎发送过来的requests对象(即网页请求的相关信息集合,包括params,data,cookies,request headers…等),会把请求的url以有序的方式排列成队,并等待引擎来提取(功能上类似于gevent库的queue模块)。
Downloader
(下载器)部门则是负责处理引擎发送过来的requests,进行网页爬取,并将返回的response(爬取到的内容)交给引擎。它对应的是爬虫流程【获取数据】这一步。
Spiders
(爬虫)部门是公司的核心业务部门,主要任务是创建requests对象和接受引擎发送过来的response(Downloader部门爬取到的内容),从中解析并提取出有用的数据。它对应的是爬虫流程【解析数据】和【提取数据】这两步。
Item Pipeline
(数据管道)部门则是公司的数据部门,只负责存储和处理Spiders部门提取到的有用数据。这个对应的是爬虫流程【存储数据】这一步。
Downloader Middlewares
(下载中间件)的工作相当于下载器部门的秘书,比如会提前对引擎大boss发送的诸多requests做出处理。
Spider Middlewares
(爬虫中间件)的工作则相当于爬虫部门的秘书,比如会提前接收并处理引擎大boss发送来的response,过滤掉一些重复无用的东西。
scrapy 工作原理
在Scrapy爬虫公司里,每个部门都各司其职,形成了很高效的运行流程
Scrapy中的程序全部都是异步模式,所有的请求或返回的响应都由引擎自动分配去处理
Scrapy的用法(豆瓣读书top250)
分析分页...
分析元素...
我们只要取出 <tr class="item">
元素下 <a>
元素的 title
属性的值、 <p class="pl">
元素、 <span class="rating_nums">
元素,就能得到书名、出版信息和评分的数据。
代码实现——创建项目
安装scrapy, pip install scrapy
解决方案1: 安装vc++运行库集合
方案2: 直接下载whl库进行安装, 简单
, 最近需要翻墙, 不知道以后怎样...
方案3: 安装vc++2015, 对应14版本, 试了,不管用, 你就别试了...
创建爬虫项目
跳转到你想创建爬虫项目的路径
创建爬虫项目
项目结构
Scrapy项目里每个文件都有特定的功能,settings.py 是scrapy里的各种设置。items.py是用来定义数据的,pipelines.py是用来处理数据的,它们对应的就是Scrapy的结构中的Item Pipeline(数据管道)middlewares.py是中间件
代码实现——编辑爬虫
如前所述,spiders是放置爬虫的目录。我们可以在spiders这个文件夹里创建爬虫文件。我们来把这个文件,命名为top250。后面的大部分代码都需要在这个top250.py文件里编写。
E:\helloSpider\douban\douban\spiders\top250.py
import scrapy import bs4 # 定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。 class DoubanSpider(scrapy.Spider): # name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'douban'意思是定义爬虫的名字为douban。等会我们启动爬虫的时候,要用到这个名字。 name = 'douban' # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。 allowed_domains = ['book.douban.com'] # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。 start_urls = ['https://book.douban.com/top250?start=0'] # parse是Scrapy里默认处理response的一个方法 def parse(self,response): print(response.text) 复制代码
之前分析过页面规律
十页变一页...
修改代码...
import scrapy import bs4 # 定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。 class DoubanSpider(scrapy.Spider): # name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'douban'意思是定义爬虫的名字为douban。等会我们启动爬虫的时候,要用到这个名字。 name = 'douban' # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。 allowed_domains = ['book.douban.com'] # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。 start_urls = [] for x in range(3): url = 'https://book.douban.com/top250?start='+str(x*25) start_urls.append(url) # parse是Scrapy里默认处理response的一个方法 def parse(self,response): print(response.text) 复制代码
提取元素....
书名是 <tr class="item">
元素下 <a>
元素的 title
属性的值;出版信息在 <p class="pl">
元素里;评分在 <span class="rating_nums">
元素里。
import scrapy import bs4 from ..items import DoubanItem # 定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。 class DoubanSpider(scrapy.Spider): # name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'douban'意思是定义爬虫的名字为douban。等会我们启动爬虫的时候,要用到这个名字。 name = 'douban' # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。 allowed_domains = ['book.douban.com'] # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。 start_urls = [] for x in range(3): url = 'https://book.douban.com/top250?start='+str(x*25) start_urls.append(url) # parse是Scrapy里默认处理response的一个方法 def parse(self, response): bs = bs4.BeautifulSoup(response.text, 'html.parser') datas = bs.find_all('tr', class_='item') for data in datas: title = data.find_all('a')[1]['title'] publish = data.find('p', class_="pl").text score = data.find('span', class_="rating_nums").text print([title, publish, score]) 复制代码
代码实现——定义数据
在scrapy中,我们会专门定义一个用于记录数据的类。
我们会实例化一个对象,利用这个对象来记录数据。
每一次,当数据完成记录,它会离开 spiders
,来到Scrapy Engine(引擎),引擎将它送入Item Pipeline(数据管道)处理。
定义这个类的py文件,正是 items.py
。
如何在items.py里定义这些数据。代码如下:
import scrapy class DoubanItem(scrapy.Item): # 让数据能以类似字典的形式记录 title = scrapy.Field() publish = scrapy.Field() score = scrapy.Field() 复制代码
修改douban250.py
import scrapy import bs4 from ..items import DoubanItem # 定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。 class DoubanSpider(scrapy.Spider): # name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'douban'意思是定义爬虫的名字为douban。等会我们启动爬虫的时候,要用到这个名字。 name = 'douban' # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。 allowed_domains = ['book.douban.com'] # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。 start_urls = [] for x in range(3): url = 'https://book.douban.com/top250?start='+str(x*25) start_urls.append(url) # parse是Scrapy里默认处理response的一个方法 def parse(self, response): bs = bs4.BeautifulSoup(response.text, 'html.parser') datas = bs.find_all('tr', class_='item') for data in datas: item = DoubanItem() item['title'] = data.find_all('a')[1]['title'] item['publish'] = data.find('p', class_="pl").text item['score'] = data.find('span', class_="rating_nums").text print(item) yield item # 类似于return, 但是不会结束函数 复制代码
代码实操——设置
我们需要修改请求头...
把 ROBOTSTXT_OBEY=True
改成 ROBOTSTXT_OBEY=False
,就是把遵守robots协议换成无需遵从robots协议,这样Scrapy就能不受限制地运行。
代码实操——运行
方法一: scrapy crawl douban(douban是我们爬虫的名字)
E:\helloSpider\douban> scrapy crawl douban
如果遇到...No module named win32api...
pip install pywin32
方法二: main.py
在最外层的大文件夹里新建一个main.py文件(与scrapy.cfg同级)
# 导入cmdline模块,可以实现控制终端命令行 from scrapy import cmdline # 执行命令 "scrapy crawl douban" cmdline.execute(['scrapy', 'crawl', 'douban']) 复制代码
了教学方便理解,先写了爬虫,再定义数据。但是,在实际项目实战中,常常顺序却是相反的——先定义数据,再写爬虫。所以,流程图应如下:
细心的你可能会发现,这一关的内容没有涉及到存储数据的步骤。
复习
存储到mysql
存储数据需要修改pipelines.py文件, 不过我们需要先建立一个数据库
drop database if exists douban; create database douban character set utf8; use douban; create table book( id int primary key auto_increment, title varchar(255) not null, publish varchar(255) not null, score decimal(2,1) not null ); 复制代码
mysql> desc book; +---------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | publish | varchar(255) | NO | | NULL | | | score | decimal(2,1) | NO | | NULL | | +---------+--------------+------+-----+---------+----------------+ 4 rows in set (0.01 sec) 复制代码
有了数据库, 我们开始写 E:\helloSpider\douban\douban\pipelines.py
# -*- coding: utf-8 -*- import pymysql class DoubanPipeline(object): def __init__(self): # 创建数据库连接 self.connection = pymysql.connect( host='localhost', port=3306, user='root', password='root', db='douban', charset='utf8' ) self.cursor = self.connection.cursor() def process_item(self, item, third): # 拼接 sql 语句 sql = "insert into book(title,publish,score) values({},{},{})".format( repr(item['title']), repr(item['publish']), item['score']) # 执行sql语句 self.cursor.execute(sql) self.connection.commit() 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 超级易懂爬虫系列之爬虫框架scrapy
- python网络爬虫(14)使用Scrapy搭建爬虫框架
- 一个咸鱼的python爬虫之路(五):scrapy 爬虫框架
- 11、web爬虫讲解2—Scrapy框架爬虫—Scrapy使用
- Scrapy框架-----爬虫
- 网络爬虫框架开发笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。