scrapy数据解析与scrapy数据的持久化存储
scrapy 数据解析
(1) extract_first() 与 extract() 函数的区别在于
- extract 返回的数据是一个列表
- extract_first 返回的数据不是一个列表数据
- response.xpath(“””//[@id=”s-hotsearch-wrapper”]/div/a[1]/div”””)[0].extract() 返回的结果是与
response.xpath(“””//[@id=”s-hotsearch-wrapper”]/div/a[1]/div”””).extract_first() 返回的结果是完全相同的
(2) xpath()中的text() 函数的使用,我这里使用一个简单的例子来说明这点:
- response.xpath(“””//*[@id=”s-hotsearch-wrapper”]/div/a[1]/div”””)extract() 返回的结果是
‘’ - response.xpath(“””//*[@id=”s-hotsearch-wrapper”]/div/a[1]/div/text()”””).extract() 返回的结果是
[‘百度热榜’]
(3) extract_first() 与 extract() 相同点:
- 两者返回的信息格式都是 selector 对象,及 scrapy 使用 xpath() 函数 进行数据筛选,将data 对象存储在 selector 对象中, selector 对象是一个list 的对象数据
scrapy 数据的持久化存储
(1) 基于终端指令的持久化存储
import scrapy
class QiubaiSpider(scrapy.Spider):
name = 'qiubai'
allowed_domains = ['https://www.qiushibaike.com/']
start_urls = ['https://www.qiushibaike.com/']
def parse(self, response):
#xpath为response中的方法,可以将xpath表达式直接作用于该函数中
odiv = response.xpath('//div[@id="content-left"]/div')
content_list = [] #用于存储解析到的数据
for div in odiv:
#xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出。
author = div.xpath('.//div[@class="author clearfix"]/a/h2/text()')[0].extract()
content=div.xpath('.//div[@class="content"]/span/text()')[0].extract()
#将解析到的内容封装到字典中
dic={
'作者':author,
'内容':content
}
#将数据存储到content_list这个列表中
content_list.append(dic)
return content_list
- 需求: 该方法只可以将parse 方法 的返回值存储到本地制定的后缀名文件中。
- 使用: 我这里提供了一个例子提供给学习参考
scrapy crawl baidu --nolog -o baidu.json
# baidu 为爬虫的名称
# --nolog 为不打印日志信息
# -o baidu.json 其中的 baidu.json 为 json 文件的名称, 其中导出的格式包括 ('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle')
# 当输出结果是中文时,请在settings.py中 添加 `FEED_EXPORT_ENCODING = 'utf-8'`
- (2) 基于管道的持久化存储(重点) ```python 爬虫文件:qiubaiDemo.py
import scrapy from secondblood.items import SecondbloodItem class QiubaidemoSpider(scrapy.Spider): name = ‘qiubaiDemo’ allowed_domains = [‘www.qiushibaike.com’] start_urls = [‘http://www.qiushibaike.com/‘] def parse(self, response): odiv = response.xpath(‘//div[@id=”content-left”]/div’) for div in odiv:
# xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出。
author = div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first()
author = author.strip('\n')#过滤空行
content = div.xpath('.//div[@class="content"]/span/text()').extract_first()
content = content.strip('\n')#过滤空行
#将解析到的数据封装至items对象中
item = SecondbloodItem()
item['author'] = author
item['content'] = content
yield item#提交item到管道文件(pipelines.py)
items文件:items.py
import scrapy class SecondbloodItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
author = scrapy.Field() #存储作者
content = scrapy.Field() #存储段子内容
- (2.1) 爬虫文件中进行书记解析
- 使用xpath()函数进行数据操作/数据解析
- (2.2) 在 items.py中进行相关属性打定义
- (2.2.1) 确定好属性值,及需要几个属性值
- (2.2.2) 进行属性定义
- (2.3) 在爬虫文件中通过解析到到文件/数据封装到 item 类型到对象中
- (2.3.1) 首先实例化一个 item 对象
- (2.3.2) 不可以通过.来进行赋值,只能通过 [属性名]的方式进行赋值
- (2.4) 在管道文件(pipelines.py)中, 接收爬虫文件传输过来到items 对象,且对其进行任何形式的持久化存储操作(核心操作)
- (2.4.1) 在相关爬虫文件(这里是baidu.py文件的 BaiduSpider 类中)函数 def parse(self, response, **kwargs) 添加 yield items, 其中 items 为 (2.3) 形成的数据
- (2.4.2) 对管道文件(pipelines.py)进行书写
- (2.4.2.1)参数说明:
- item: 接收的item对象,其中 item 对象其实就是一个 dict(字典型) 的数据对象
- (2.4.2.2)在接收 item 对象时,一次只能接收一个管道文件,说明该方法必须调用多次已实例化对象
- (2.4.2.3)当保存到相关的文本文件或相关文件中
- (2.4.2.3.1)不能在 process_item 函数中进行open 操作,应该重写 父类中的两个方法
- (2.4.2.3.1.1) def open_spider(self, spider):打开文件的方法,只会在爬虫在最开始启动时候执行一次
- (2.4.2.3.1.2) def close_spider(self, spider):关闭文件,只会在爬虫结束的时候执行一次
- (2.4.2.3.1.3) 并且在 def process_item(self, item, spider) 中进行写入操作
```python
# 这是一个demo 案例
from itemadapter import ItemAdapter
class Day01Pipeline:
fp = None
# 打开文件的方法,只会在爬虫在最开始启动时候执行一次
def open_spider(self, spider):
self.fp = open("textile.txt", "w", encoding="utf-8")
# 关闭文件,只会在爬虫结束的时候执行一次
def close_spider(self, spider):
self.fp.close()
def process_item(self, item, spider):
# 在接收 item 对象时,一次只能接收一个管道文件,说明该方法必须调用多次已实例化对象
self.fp.write("写入内容")
return item
(2.5) 在配置文件中开启管道机制
(2.5.1) 管道文件的相关配置在 settings.py 中 的 ITEM_PIPELINES 参数中,我这里提供了一个实例
ITEM_PIPELINES = { 'First.pipelines.Day01Pipeline': 300, }
- 参数说明
- 300 表示管道类的优先级, 数值越小,优先级越高,越先执行
- 其中的 ITEM_PIPELINES 是一个字典型的数据格式
- 其中的 ‘Day_01.pipelines.Day01Pipeline’ 表示管道文件的相关路径
- 参数说明