scrpy基础
今天是复习前几天搞得scrapy爬虫框架学习 好长时间没有在搞了,属实是有一些东西给忘了 今天特地给复习一下,这是房价前所听课所作的笔记
代码语言:javascript复制创建目录 scrapy startproject {firstblood}文件名
在spider目录下创建一个爬虫源文件scrapy genspider {first} {www.XXX.com}这个可以是一个随便的网址,后续文件中是可以改的
{first}创建的爬虫源文件的名称
scrapy crawl {first}创建的爬虫源文件名称
ROBOTSTXT_OBEY = False要把这个设置成False要不然是得不到所想要的response响应信息
scrapy crawl first --nolog只运行代爬虫源文件的输出信息
但是可以通过添加到setting.py
#显示指定的类型的日志信息
LOG_LEVEL='ERROR'
这样就可以把你爬虫源文件中的错误信息一同给报出来 这个你是用
scrapy crawl first --nolog
所不能够实现的
所以还是建议使用添加LOG_LEVEL
针对于一些导入item管道类要进行一下操作
下面是爬取糗事百科的段子的qiubai.py的代码,运行要使用scrapy crawl qiubai
代码语言:javascript复制import scrapy
class QiubaiSpider(scrapy.Spider):
name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/text/']
def parse(self, response):#数据解析的方法应该卸载这个里边
#解析 作者的名称和段子内容
print(response)
div_list=response.xpath('/html/body/div[1]/div/div[2]/div')#跟etree是不一样的两个方法 但是用法是几乎一样的
for div in div_list:
# auther=div.xpath('./div[1]/a[2]/h2/text()')[0].extract()#这中间只有一个列表元素那么就是用[0]给他拿出来之后再进行读取
auther = div.xpath('./div[1]/a[2]/h2/text()').extract_first()#要想使用这个extract_first()那么你必须要保证你这个xpath对应的数据只有一个之这样才能用这个给这第0个给读取出来
#.extact()可以将Selector中的data中的数据给读取出来
content=div.xpath('./a[1]/div/span//text()').extract()#文本之中要还是有子标签那就要使用双斜杠,要不然只能爬取第一个数据
#如果这个中有很多元素,那么用.extract会返回一个列表那么就可以通过转换成字符串
content=''.join(content)
#这个xpath返回的一定是一个列表,列表类型是一个Selector对象,那么我们应该获取data中的数据
print(auther,content)
中间的xpath数据解析和那个etree中的xpath不是一个东西但是用法是一样的,要注意区别和是使用 主要区别就是etree中的xpath返回的是一个字符串,而scrapy中的xpath返回的是一个Selector类型,需要使用.extact()将其中的元素给读取出来 由于结果太长,我就只粘贴一组结果
代码语言:javascript复制<200 https://www.qiushibaike.com/text/>
乡村农民小哥哥
早上10点登桂林尧山,观景平台上,一处卖岩蜜的,没错就是菜市场大家见过的,和石头一样的蜂蜜结晶,需要一把锋利的刀才能砍下来卖的,开始觉得新奇,买了20
块钱一包,吃起来味道也有蜂蜜味道,不由感叹这桂林尧山产这些独特的风味小吃,风景优美,美食遍地,美女如林,真是一大美事!下午3点,开始拉肚子,网络一查
,所谓岩蜜都是糖和各种料制作的假货,新闻早就曝光过……在这里我就想问一下,那个锋利的砍岩石刀在哪可以买得到?!
持久化存储
基于终端命令
接下来进行持久化存储 这一共分为两种一个是通过终端指令
代码语言:javascript复制scrapy crawl qiubai -o ./qiubai.csv
这个文件名为qiubai 存储的文件名为 qiubai.csv 而且文件类型只能是特定类型,不能是txt类型
基于管道1
**items.py **定义相关的属性
代码语言:javascript复制class QiubaiproItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
author = scrapy.Field()
content = scrapy.Field()
pass
pipelines.py 专门用来处理item对象的
在管道类中的process_item
代码语言:javascript复制class QiubaiproPipeline:
fp=None
def open_spider(self, spider):
print("开始爬虫")
self.fp=open('./qiubai.txt','w',encoding='utf-8')
#专门用来处理item类型对象
def process_item(self, item, spider):
#该方法可以接受爬虫文件提交过来的item对象
#该方法没接收到一个item就会被调用一次
author=item["author"]
content=item["content"]
self.fp.write(author ':' content 'n')
return item#item #就会传递给下一个即将执行的管道类
def close_spider(self,spider):
self.fp.close()
print('结束爬虫')
settings.py在配置文件中开启管道(默认情况下是不开启管道的)
代码语言:javascript复制ITEM_PIPELINES = {
'qiubaipro.pipelines.QiubaiproPipeline': 300,
}
'''开启管道 300表示的是优先级,数值越小的优先级越高'''
qiubai.py
代码语言:javascript复制import scrapy
from qiubaipro.items import QiubaiproItem
class QiubaiSpider(scrapy.Spider):
name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/text/']
# def parse(self, response):#数据解析的方法应该卸载这个里边
# #解析 作者的名称和段子内容
# print(response)
# all_data=[]
# div_list=response.xpath('/html/body/div[1]/div/div[2]/div')#跟etree是不一样的两个方法 但是用法是几乎一样的
# for div in div_list:
# # auther=div.xpath('./div[1]/a[2]/h2/text()')[0].extract()#这中间只有一个列表元素那么就是用[0]给他拿出来之后再进行读取
# author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()#要想使用这个extract_first()那么你必须要保证你这个xpath对应的数据只有一个之这样才能用这个给这第0个给读取出来
# #.extact()可以将Selector中的data中的数据给读取出来
# content=div.xpath('./a[1]/div/span//text()').extract()#文本之中要还是有子标签那就要使用双斜杠,要不然只能爬取第一个数据
# #如果这个中有很多元素,那么用.extract会返回一个列表那么就可以通过转换成字符串
# content=''.join(content)
# #这个xpath返回的一定是一个列表,列表类型是一个Selector对象,那么我们应该获取data中的数据
# print(author,content)
#
# dic={
# 'auther':author,
# 'content':content
# }
# all_data.append(dic)
# ##持久化存储 基于终端命令
# return all_data
def parse(self, response):#数据解析的方法应该卸载这个里边
#解析 作者的名称和段子内容
print(response)
all_data=[]
div_list=response.xpath('/html/body/div[1]/div/div[2]/div')#跟etree是不一样的两个方法 但是用法是几乎一样的
for div in div_list:
# auther=div.xpath('./div[1]/a[2]/h2/text()')[0].extract()#这中间只有一个列表元素那么就是用[0]给他拿出来之后再进行读取
author = div.xpath('./div[1]/a[2]/h2/text()|./div[1]/span/h2/text()').extract_first()#要想使用这个extract_first()那么你必须要保证你这个xpath对应的数据只有一个之这样才能用这个给这第0个给读取出来
# 加了一组xpath解析就是为了找到匿名用户的信息
#.extact()可以将Selector中的data中的数据给读取出来
content=div.xpath('./a[1]/div/span//text()').extract()#文本之中要还是有子标签那就要使用双斜杠,要不然只能爬取第一个数据
#如果这个中有很多元素,那么用.extract会返回一个列表那么就可以通过转换成字符串
content=''.join(content)
#这个xpath返回的一定是一个列表,列表类型是一个Selector对象,那么我们应该获取data中的数据
print(author,content)
item= QiubaiproItem()
item["author"]=author
item["content"]=content
yield item#将item提交给了管道
基于管道2
面试题:将爬虫爬取下来的数据,一份数据存到本地,一份数据存到数据库
保存到数据库和本地
pipelines.py
代码语言:javascript复制# 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 sqlite3
class QiubaiproPipeline:
fp=None
def open_spider(self, spider):
print("开始爬虫")
self.fp=open('./qiubai.txt','w')
#专门用来处理item类型对象
#该方法可以接受爬虫文件提交过来的item对象
#该方法没接收到一个item就会被调用一次
def process_item(self, item, spider):
author=item["author"]
content=item["content"]
self.fp.write(author ':' content 'n')
return item#item 就会传递给下一个即将执行的管道类
def close_spider(self,spider):
self.fp.close()
print('结束爬虫')
############################################
#管道文件中的一个管道类对应的数据存储到一个平台或者载体之中
class mysqlPipeline:
def open_spider(self, spider):
print("开始爬虫")
self.conn=sqlite3.connect("qiubai.db")
cur=self.conn.cursor()
cur.execute('''create table if not exists qiubai(author primary key,content)''')
def process_item(self,item,spider):
author = item["author"]
content = item["content"]
self.cursor=self.conn.cursor()
try:
self.cursor.execute('''insert into qiubai values(?,?)''',(author,content))
print(item["author"],"添加到数据库成功")
self.conn.commit()
except Exception as e :
print(e)
self.conn.rollback()#数据回滚
return item
def close_spider(self,spider):
self.cursor.close()
self.conn.close()
# 爬虫文件提交的item类型的对象,最终会提交哪一个管道类:
# 先执行的管道类
settings.py
代码语言:javascript复制ITEM_PIPELINES = {
'qiubaipro.pipelines.QiubaiproPipeline': 300,
'qiubaipro.pipelines.mysqlPipeline': 301,
}
'''开启管道 300表示的是优先级,数值越小的优先级越高'''
代码语言:javascript复制scrapy 持久化存储
--基于终端命令:
-要求: 只可以将parse方法 的返回值存储到本地的文本文件中,不能存储到数据库中
-注意: 持久化存储对应的文本文件的类型只可以为:'json','jsonlines','jl','csv','xml','marshal','pickle'
-指令: scrapy crawl XXX -o filePath
-好处: 他非常的高效便捷
-缺点: 局限性比较强(数据只能存储到指定后缀的我呢本文件中)
--基于管道:
-编码流程:
- 数据解析
- 在item类当中定义相关属性 (在item中)
- 将解析的数据封装存储到item类型的对象中
- 将item类型的对象提交给管道进行持久化存储的操作
- 在管道类中的process_item中将其接受到的item对象中存储的数据进行持久化存储操作 (在pipelines里边)
- 在配置文件中开启管道
--过程:
运行程序
代码语言:javascript复制scrapy crawl qiubai