scrapy爬取糗事百科段子

2022-08-18 16:12:53 浏览数 (1)

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

0 人点赞