以前我们写爬虫,要导入和操作不同的模块,比如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框架-----爬虫
- 网络爬虫框架开发笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
正则表达式必知必会
Ben Forta / 杨涛、王建桥、杨晓云 / 人民邮电出版社 / 2007 / 29.00元
正则表达式是一种威力无比强大的武器,几乎在所有的程序设计语言里和计算机平台上都可以用它来完成各种复杂的文本处理工作。本书从简单的文本匹配开始,循序渐进地介绍了很多复杂内容,其中包括回溯引用、条件性求值和前后查找,等等。每章都为读者准备了许多简明又实用的示例,有助于全面、系统、快速掌握正则表达式,并运用它们去解决实际问题。 本书适合各种语言和平台的开发人员。一起来看看 《正则表达式必知必会》 这本书的介绍吧!
正则表达式在线测试
正则表达式在线测试
RGB HSV 转换
RGB HSV 互转工具