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.youkuaiyun.com

5、完善爬虫
在上一步生成出来的爬虫文件中编写指定网站的数据采集操作,实现数据提取。
步骤如下:
01、修改起始URL;
02、检查修改允许的域名;
03、在parse方法中实现爬取逻辑;
5.1 在./lufeitest/lufeitest/spiders/csdntest.py中修改内容
生成的初始内容如下:
class CsdntestSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['itcast.cn'] # 02、检查域名
start_urls = ['https://www.itcast.cn/channel/teacher.shtml#ajavaee'] # 01、修改起始URL
# 03、在parse方法中实现爬取逻辑
def parse(self, response):
# 定义对于网站的相关操作
# 获取老师节点列表;
node_list = response.xpath('//div[@class="li_txt"]')
# print(len(node_list))
# 遍历老师节点列表
for node in node_list:
ter_temp = {}
# xpath方法返回的是选择器对象列表
# ter_temp['name'] = node.xpath('./h3/text()')[0].extract() # extract()从xpath选择器对象中提取数据,但是当前面选择器输出的内容为空列表时,会报错。当列表值为多个时建议使用extract().
# ter_temp['jibie'] = node.xpath('./h4/text()')[0].extract()
# ter_temp['jianjie'] = node.xpath('./p/text()')[0].extract()
ter_temp['name'] = node.xpath('./h3/text()').extract_first() # extract_first()当前面的选择器为空列表时,其不会报错,会显示值为None,如果不是空列表,会拿到第一个结果。当前面列表只有一个值时,建议使用extract_first().
ter_temp['jibie'] = node.xpath('./h4/text()').extract_first()
ter_temp['jianjie'] = node.xpath('./p/text()').extract_first()
# print(ter_temp)
yield ter_temp # scrapy返回数据,通常使用yield,好处是可以实现翻页操作。所以不使用return返回数据
注意点:
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
三 、数据建模
通常在做项目的过程中,在items.py中进行数据建模
为什么建模
1、定义item即提前规划好哪些字段需要抓,防止手误,因为定义好之后,在运行过程中,系统会自动检查
2、配合注释一起可以清晰的知道要抓取哪些字段,没有定义的字段不能抓取,在目标字段少的时候可以使用字典代替
3、使用scrapy的一些特定组件需要Item做支持,如scrapy的ImagesPipeline管道类,百度搜索了解更多
1、如何建模
在items.py文件中定义要提取的字段:
示例:
import scrapy
class LufeitestItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field() # 讲师名称
Lecturer_level = scrapy.Field() # 讲师级别
introduction = scrapy.Field() # 讲师简介
2、如何使用模板类
1、在爬虫文件中导入模板类;示例如下:
from lufeitest.items import LufeitestItem
2、在爬虫文件中,之前定义的字典,需要替换为实例item对象;示例如下:
# 实例化items对象
item = LufeitestItem()
3、因pipelines.py中做的是保存数据,使用了对字典对象进行序列化操作,但item对象引入后非字典格式,需要转化为字典,否则会报错;示例如下:
# 将item强制转换为字典对象,该操作只能再scapy中使用
item = dict(item)
实例代码如下:
爬虫文件文件中的代码:
import scrapy
from lufeitest.items import LufeitestItem
class CsdntestSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['itcast.cn'] # 02、检查域名
start_urls = ['https://www.itcast.cn/channel/teacher.shtml#ajavaee'] # 01、修改起始URL
# 03、在parse方法中实现爬取逻辑
def parse(self, response):
# 定义对于网站的相关操作
# 获取老师节点列表;
node_list = response.xpath('//div[@class="li_txt"]')
# print(len(node_list))
# 遍历老师节点列表
for node in node_list:
# ter_temp = {} # 将自定义的字典去掉
# 实例化items对象
item = LufeitestItem()
# xpath方法返回的是选择器对象列表
# item['name'] = node.xpath('./h3/text()')[0].extract() # extract()从xpath选择器对象中提取数据,但是当前面选择器输出的内容为空列表时,会报错。当列表值为多个时建议使用extract().
# item['jibie'] = node.xpath('./h4/text()')[0].extract()
# item['jianjie'] = node.xpath('./p/text()')[0].extract()
item['name'] = node.xpath('./h3/text()').extract_first() # extract_first()当前面的选择器为空列表时,其不会报错,会显示值为None,如果不是空列表,会拿到第一个结果。当前面列表只有一个值时,建议使用extract_first().
item['Lecturer_level'] = node.xpath('./h4/text()').extract_first()
item['introduction'] = node.xpath('./p/text()').extract_first()
# print(item)
yield item # scrapy返回数据,通常使用yield,好处是可以实现翻页操作。所以不使用return返回数据
pipeline管道文件中的代码如下:
import json
class LufeitestPipeline:
def __init__(self): # 创建并打开文件
self.file = open('itcast.jsons','w')
def process_item(self, item, spider):
# 爬虫文件中提取数据的方法每yield一次item,就会运行一次
# 该方法为固定名称函数
# print('itcast',item) # 直接打印
# 将item强制转换为字典对象,该操作只能再scapy中使用
item = dict(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()
注意:
1、from lufeitest.items import LufeitestItem这一行代码中 注意item的正确导入路径,忽略pycharm标记的错误
2、python中的导入路径要诀:从哪里开始运行,就从哪里开始导入
3、开发流程总结
1、创建项目
scrapy startproject 项目名
2、明确目标
在items.py文件中进行建模
3、创建爬虫
3.1 创建爬虫
scrapy genspider 爬虫名 允许的域
3.2 完成爬虫
修改start_urls
检查修改allowed_domains
编写解析方法
4、保存数据
在pipelines.py文件中定义对数据处理的管道
在settings.py文件中注册启用管道
本文介绍Scrapy爬虫框架的基本概念、工作流程及使用方法。包括安装配置、项目创建、爬虫编写、数据提取与保存等核心内容。
4802

被折叠的 条评论
为什么被折叠?



