scrapy的入门使用
学习目标:
- 掌握 scrapy的安装
- 应用 创建scrapy的项目
- 应用 创建scrapy爬虫
- 应用 运行scrapy爬虫
- 应用 scrapy定位以及提取数据或属性值的方法
- 掌握 response响应对象的常用属性
1 安装scrapy
命令:sudo apt-get install scrapy
或者:pip/pip3 install scrapy
2 scrapy项目开发流程
- 创建项目:
scrapy startproject mySpider
- 生成一个爬虫:
scrapy genspider itcast itcast.cn
- 提取数据:根据网站结构在spider中实现数据采集相关内容
- 保存数据:使用pipeline进行数据后续处理和保存
3. 创建项目
通过命令将scrapy项目的的文件生成出来,后续步骤都是在项目文件中进行相关操作,下面以抓取传智师资库来学习scrapy的入门使用:http://www.itcast.cn/channel/teacher.shtml
创建scrapy
项目的命令:scrapy startproject <项目名字>
示例:scrapy startproject myspider
生成的目录和文件结果如下:
PS C:\Users\myxc\Documents\code\python\demo_spider> tree /f
卷 Windows 的文件夹 PATH 列表
卷序列号为 68B5-629B
C:.
│ scrapy.cfg
│
└─demo_spider
│ items.py
│ middlewares.py
│ pipelines.py
│ settings.py
│ __init__.py
│
└─spiders
__init__.py
4. 创建爬虫
通过命令创建出爬虫文件,爬虫文件为主要的代码作业文件,通常一个网站的爬取动作都会在爬虫文件中进行编写。
命令:scrapy genspider <爬虫名字> <允许爬取的域名>
(在项目路径下执行)
爬虫名字: 作为爬虫运行时的参数
允许爬取的域名:为对于爬虫设置的爬取范围,设置之后用于过滤要爬取的url,如果爬取的url与允许的域不通则被过滤掉。
示例:
PS C:\Users\myxc\Documents\code\python\demo_spider> scrapy genspider itcast itcast.cn
Created spider 'itcast' using template 'basic' in module:
demo_spider.spiders.itcast
PS C:\Users\myxc\Documents\code\python\demo_spider> tree /f
卷 Windows 的文件夹 PATH 列表
卷序列号为 68B5-629B
C:.
│ scrapy.cfg
│
└─demo_spider
│ items.py(自己预计需要爬取的内容)
│ middlewares.py(自定义中间件的地方)
│ pipelines.py(管道,用于保存数据)
│ settings.py(设置文件、UA、启动管道)
│ __init__.py
│
├─spiders(自己定义的spider文件夹)
│ │ itcast.py(定义spider的文件)
│ │ __init__.py
│ │
│ └─__pycache__
│ __init__.cpython-37.pyc
│
└─__pycache__
settings.cpython-37.pyc
__init__.cpython-37.pyc
5. 完善爬虫
在上一步生成出来的爬虫文件中编写指定网站的数据采集操作,实现数据提取
5.1 在/myspider/myspider/spiders/itcast.py中修改内容如下:
import scrapy
class ItcastSpider(scrapy.Spider):
# 定义爬虫名称
name = 'itcast'
# 定义爬虫解析域
allowed_domains = ['itcast.cn']
# 定义爬虫起始url
start_urls = ['http://www.itcast.cn/channel/teacher.shtml#ajavaee']
def parse(self, response):
# 定义页面解析的操作
# with open("itcast.html", "wb") as f:
# f.write(response.body)
teacher_list = response.xpath("//div[contains(@class, 'tea_txt')]//li")
# print(len(teacher_list))
for teacher in teacher_list:
temp_dict = {}
# temp_dict['name'] = teacher.xpath("//h3/text()") # 注意加点和不加点的区别!!!
temp_dict['name'] = teacher.xpath(".//h3/text()").extract_first()
temp_dict['position'] = teacher.xpath(".//h4/text()")[0].extract()
temp_dict['info'] = teacher.xpath(".//p/text()")[0].extract().replace('\r\n', '')
# temp_dict['position'] = teacher.xpath("//h2/span/text()")
# temp_dict['name'] = teacher.xpath("//p[1]")
print(temp_dict)
注意:
- scrapy.Spider爬虫类中必须有名为parse的解析
- 如果网站结构层次比较复杂,也可以自定义其他解析函数
- 在解析函数中提取的url地址如果要发送请求,则必须属于allowed_domains范围内,但是start_urls中的url地址不受这个限制,我们会在后续的课程中学习如何在解析函数中构造发送请求
- 启动爬虫的时候注意启动的位置,是在项目路径下启动
- parse()函数中使用yield返回数据,注意:解析函数中的yield能够传递的对象只能是:BaseItem, Request, dict, None
5.2 定位元素以及提取数据、属性值的方法
解析并获取scrapy爬虫中的数据: 利用xpath规则字符串进行定位和提取
- response.xpath方法的返回结果是一个类似
list
的类型,其中包含的是selector
对象,操作和列表一样,但是有一些额外的方法 - 额外方法
extract()
:返回一个包含有字符串的列表 - 额外方法
extract_first()
:返回列表中的第一个字符串,列表为空没有返回None - 在提取的元素内再次进行提取时,要注意:
//h3/text()
改方法会提取页面内所有元素,并不会从当前元素下提取,正确的方法是:.//h3/text()
。
两种提取方法的区别:当xpath
获取的元素只有一个时,使用extract_first()
可以直接提取列表的第一个元素,不需要再加上索引[0]
,同时,使用extract_first()
时,如果xpath
未获取元素,会返回一个None
,并不会报错;使用extract()
提取时,必须要在数组后加上索引值,同时,若xpath
提取对象为空(即列表长度为0),那么将报错,程序终止运行。
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文件中定义对数据的操作
- 定义一个管道类
- 重写管道类的process_item方法
- process_item方法处理完item之后必须返回给引擎
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json # 导入json处理模块
class DemoSpiderPipeline:
def __init__(self):
self.file = open('itcast.json', 'w', encoding='utf-8') # 设置打开格式,防止保存后乱码
def process_item(self, item, spider):
json_data = json.dumps(item, ensure_ascii=False)+',\n' # json格式化
self.file.write(json_data) # 写入json数据
return item # 数据处理完毕将数据返回给爬虫引擎
def __del__(self):
self.file.close()
6.2 在settings.py配置启用管道
ITEM_PIPELINES = {
'myspider.pipelines.ItcastPipeline': 400
}
配置项中键为使用的管道类,管道类使用.进行分割,第一个为项目目录,第二个为文件,第三个为定义的管道类。配置项中值为管道的使用顺序,设置的数值约小越优先执行,该值一般设置为1000以内。
未在设置里激活Pipeline之前,可以看到爬虫运行时打印的日志中开启的管道列表为空:
(开启管道前)
2020-08-27 16:02:08 [scrapy.middleware] INFO: Enabled item pipelines:
[]
(开启管道后)
2020-08-27 16:08:28 [scrapy.middleware] INFO: Enabled item pipelines:
['demo_spider.pipelines.DemoSpiderPipeline']
7. 运行scrapy
命令:在项目目录下执行scrapy crawl <爬虫名字>
示例:scrapy crawl itcast
PS C:\Users\myxc\Documents\code\python\demo_spider> scrapy crawl itcast --nolog (不打印运行日志)
小结
- scrapy的安装:pip install scrapy
- 创建scrapy的项目: scrapy startproject myspider
- 创建scrapy爬虫:在项目目录下执行 scrapy genspider itcast itcast.cn
- 运行scrapy爬虫:在项目目录下执行 scrapy crawl itcast
解析并获取scrapy爬虫中的数据:
- response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法
- extract() 返回一个包含有字符串的列表
- extract_first() 返回列表中的第一个字符串,列表为空没有返回None
scrapy管道的基本使用:
- 完善pipelines.py中的process_item函数
- 在settings.py中设置开启pipeline
response响应对象的常用属性
- response.url:当前响应的url地址
- response.request.url:当前响应对应的请求的url地址
- response.headers:响应头
- response.requests.headers:当前响应的请求头
- response.body:响应体,也就是html代码,byte类型
- response.status:响应状态码