学习目标
(1)创建一个Scrapy项目
(2)定义提取的结构化数据(Item)
(3)编写爬取网站的Spider并提取出结构化数据(Item)
(4)编写Item Pipeline来存储提取到的Item(既,结构化数据)
1 创建Scrapy项目
cmd终端执行:scrapy startproject XXX——创建名为xxx的项目
ITcast项目:
①ITcast文件夹
spider文件夹
_ _ init _ _.py
items.py
middlewares.py
pipelines.py
settings.py
②scrapy.cfg
①ITcas文件夹:包含6个子文件
**items.py:**用于定义item字段,我们的目标
**middleware.py:**定义中间件
**pipelines.py:**定义处理item字段的方法
**settings.py:**项目的配置文件
**spider文件夹:**在此文件夹下创建爬虫
②scrapy.cfg:ITcast项目的配置文件,自动生成一般不需要修改
2 定义提取的结构化数据(Item)
例:打算抓取:http://www.itcast.cn/channel/teacher.shtml网站例的所有讲师的姓名、职称和个人信息。
1.打开项目文件夹里的item.py文件
2.item定义结构化数据字段,用来保存爬取到的数据,有点像python中的dict,但是提供了一些额外的保护来减少错误。
3.可以通过创建一个scrapy.Item类,并且定义类型为scrapy.Field的类属性来定义一个Item(可以理解成类似于ORM的映射关系)
4.接下来创建一个ItcastItem类,和构建item模型。
3 创建爬虫,并取出结构化数据(item)
(1)创建爬虫文件模板: 在spider文件夹下,运行cmd并执行scrapy genspider XXX "域名”
(2)编写爬虫文件:其中使用Xpath提取网页中的item数据
import scrapy
#导入item文件中的ItcastItem
from ITcast.items import ItcastItem
class ItcastSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['itcast.cn']
start_urls = ['http://www.itcast.cn/channel/teacher.shtml']
def parse(self, response):
items=[]
for each in response.xpath("//div[@class='li_txt']"):
item=ItcastItem()
#extract()方法将xpath对象转换为unicode字符串
name=each.xpath("h3/text()").extract()
title = each.xpath("h4/text()").extract()
info = each.xpath("p/text()").extract()
#xpath返回的是包含一个元素的列表
item['name']=name[0]
item['level']=title[0]
item['info']=info[0]
items.append(item)
#返回最终数据:返回给引擎
return items
(3)运行爬虫文件,同时 保存数据
保存数据方法可以分为4种:-o输出指定格式文件,命令如下
json格式,默认为unicode编码:scrapy crawl itcast -o teachers.json
json lines格式,默认为unicode编码:scrapy crawl itcast -o teachers.jsonl
csv格式,逗号表达式可以用excel打开:scrapy crawl itcast -o teachers.csv
xml格式:scrapy crawl itcast -o teachers.xml
4 Item Pipeline处理提取到的Item
爬虫文件的返回值,会送入到引擎,引擎会进行判断:
(1)如果返回的是item字段:那么引擎会传递给item pipeline组件
(2)如果返回的是scrapy.request():那么引擎会判断这是一个请求,会将该请求传递给调度器。
当item在spider中被搜集之后,它将会被传递到引擎,引擎再将item传递给item pipeline,这些item pipeline组件按照定义的顺序处理item。每个item pipeline都实现了简单方法的python类,比如决定item是丢弃还是存储。以下是item pipeline的典型应用:
1.验证爬取的数据(检查item包含某些字段,比如说name字段)
2.查重(并丢弃)
3.将爬取的数据保存到文件或者数据库中
(1)编写pipeline文件
# 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
class ItcastPipeline:
def __init__(self):
#可选实现,做参数初始化等
self.file=open('teacher.json','wb')
def process_item(self, item, spider):
'''
:param item: spider提取的item
:param spider: 爬取item的spider
:return:
这个方法必须实现,每个item pipeline组件都需要调用该方法,
这个方法返回一个item,被丢弃的item将不会被之后的pipeline
组件处理。
'''
content=json.dumps(dict(item),ensure_ascii=False)+'\n'
self.file.write(bytes(content,encoding='utf8'))
return item
def open_spider(self,spider):
#可选实现,当spider被开启是,这个方法被调用
pass
def close_spider(self,spider):
#可选实现,当spider被关闭时,这个方法被调用
self.file.close()
(2)启用一个pipeline组件
为了启用item pipeline组件,必须将它的类添加到settings.py文件ITEM_PIPELINES配置,分配给每个pipeline类整型值,确定运行顺序,按数字从低到高的顺序,通过pipeline,通常这些数字定义在0-1000范围内(数值越低,组件的优先级越高)
(3)运行爬虫