Python爬虫学习第十二天—scrapy学习
一、scrapy的概念和流程
1、scrapy概念
Scrapy是一个Python编写的开源网络爬虫框架,它是一个被设计用于爬取网络数据、提取结构性数据的框架。
Scrapy文档地址:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html
2、scrapy工作流程
其流程可以描述如下:
1.爬虫中起始的url构造成request对象-->爬虫中间件-->引擎-->调度器
2.调度器把request-->引擎-->下载中间件--->下载器
3.下载器发送请求,获取response响应---->下载中间件---->引擎--->爬虫中间件--->爬虫
4.爬虫提取url地址,组装成request对象---->爬虫中间件--->引擎--->调度器,重复步骤2
5.爬虫提取数据--->引擎--->管道处理和保存数据
注意:
图中中文是为了方便理解后加上去的
图中绿色线条的表示数据的传递
注意图中中间件的位置,决定了其作用
注意其中引擎的位置,所有的模块之前相互独立,只和引擎进行交互
2.1 scrapy的三个内置对象
request请求对象:由url method post_data headers等构成。
response响应对象:由url body status headers等构成。
item数据对象:本质是个字典。
2.2 scrapy中每个模块的具体作用
二、scrapy的入门使用
1、安装scrapy
centos 7:pip/pip3 install scrapy
ubuntu: sudo apt-get install scrapy
2、scrapy项目开发流程
1、创建项目
scrapy startproject mySpider
2、生成一个爬虫,需要进入项目目录后执行如下命令;
scrapy genspider douluodalu ibiquge.la
3、提取数据
spider中实现数据采集相关内容。
4、保存数据
利用管道pipeline来处理(保存)数据。
3、创建项目
通过命令将scrapy项目的的文件生成出来;
创建scrapy 项目的命令:
scrapy start project <项目名称>
示例:
scrapy startproject lufeitest
生成目录如下:
4、创建爬虫
进入项目目录:cd lufeitest/
执行命令:scrapy genspider <爬虫名称> <允许爬取的域名>
爬虫名字: 作为爬虫运行时的参数
允许爬取的域名: 为对于爬虫设置的爬取范围,设置之后用于过滤要爬取的url,如果爬取的url与允许的域不通则被过滤掉。
示例:
cd lufeitest/
scrapy genspider csdntest www.csdn.net
5、完善爬虫
在上一步生成出来的爬虫文件中编写指定网站的数据采集操作,实现数据提取。
步骤如下:
01、修改起始URL;
02、检查修改允许的域名;
03、在parse方法中实现爬取逻辑;
5.1 在./lufeitest/lufeitest/spiders/csdntest.py中修改内容
生成的初始内容如下:
class CsdntestSpider ( scrapy. Spider) :
name = 'itcast'
allowed_domains = [ 'itcast.cn' ]
start_urls = [ 'https://www.itcast.cn/channel/teacher.shtml#ajavaee' ]
def parse ( self, response) :
node_list = response. xpath( '//div[@class="li_txt"]' )
for node in node_list:
ter_temp = { }
ter_temp[ 'name' ] = node. xpath( './h3/text()' ) . extract_first( )
ter_temp[ 'jibie' ] = node. xpath( './h4/text()' ) . extract_first( )
ter_temp[ 'jianjie' ] = node. xpath( './p/text()' ) . extract_first( )
yield ter_temp
注意点:
1、scrapy.Spider爬虫类中必须有名为parse的解析
2、如果网站结构层次比较复杂,也可以自定义其他解析函数
3、在解析函数中提取的url地址如果要发送请求,则必须属于allowed_domains范围内,但是start_urls中的url地址不受这个限制,我们会在后续的课程中学习如何在解析函数中构造发送请求
4、启动爬虫的时候注意启动的位置,是在项目路径下启动
5、parse()函数中使用yield返回数据,注意:解析函数中的yield能够传递的对象只能是:BaseItem, Request, dict, None
5.2 定位元素以及提取数据、属性值的方法
解析并获取scrapy爬虫中的数据: 利用xpath规则字符串进行定位和提取
response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法
额外方法extract():返回一个包含有字符串的列表
额外方法extract_first():返回列表中的第一个字符串,列表为空没有返回None
5.3 response响应对象的常用属性
response.url:当前响应的url地址
response.request.url:当前响应对应的请求的url地址
response.headers:响应头
response.requests.headers:当前响应的请求头
response.body:响应体,也就是html代码,byte类型
response.status:响应状态码
6、保存数据
利用管道pipeline来处理(保存)数据。
6.1 在pipelines.py文件中对数据操作
1、定义一个管道类
2、重写管道类process_item方法
3、process_item方法处理万item之后必须返回给引擎。
示例1:直接打印数据
import json
class LufeitestPipeline:
# 爬虫文件中提取数据的方法每yield一次item,就会运行一次
# 该方法为固定名称函数
def process_item(self, item, spider):
print(item)
return item
示例2:将数据写入文件
import json
class LufeitestPipeline:
def __init__(self): # 创建并打开文件
self.file = open('itcast.jsons','w')
def process_item(self, item, spider):
# 爬虫文件中提取数据的方法每yield一次item,就会运行一次
# 该方法为固定名称函数
print('itcast',item) # 直接打印
# 将数据序列化
json_data = json.dumps(item,ensure_ascii=False) + ',\n' # ",\n"加上换行符,ensure_ascii=False转换为中文。
# 将序列化的数据写入文件
self.file.write(json_data)
return item
def __del__(self): # 关闭文件
self.file.close()
6.2 在settings.py配置启用管道
ITEM_PIPELINES = {
'lufeitest.pipelines.LufeitestPipeline': 300,
}
说明:
配置项中键为使用的管道类,管道类使用.进行分割,第一个为项目目录,第二个为文件,第三个为定义的管道类。
配置项中可以设置多个管道类;
配置项中值为管道的使用顺序,设置的数值约小越优先执行,该值一般设置为1000以内。
7. 运行scrapy
命令:在项目目录下执行scrapy crawl <爬虫名字>
示例:scrapy crawl itcast 或scrapy crawl itcast --nolog