scrapy学习笔记(八)

这篇文章主要目的是引入数据库

任务A:逐页爬取散文网经典散文信息

分析网页特征:翻页是通过对https://www.sanwen.net/sanwen/?p=6最后的数字进行逐加,总共十页考虑使用for循环进行逐页解析。

图一 网页翻页网址数字特征

网页xpath解析发现文章基本信息被放在了一个ul标签下,分装在不同的li标签中,简单提取即可。

图二 网页xpath分析

新建工程三连:

scrapy startproject sanwen

cd sanwen

scrapy genspider sanwen sanwen.net

然后重点来了,学习python自带数据库模块sqlite3用法,按理来说应该用代码去实现连接数据库,创建数据表和添加表单信息,但是本人还是采用了舒服的可视化软件SQLiteStudio来完成数据库的创建操作。

1. 创建数据库sanwen.sqlite,在sanwen工作目录下

2. 新建表sanwen,添加列“title”,“time”,“author”,“url”,变量类型都设置为VARCHAR,确定生成表格commit structure changes,在数据页就可以看到表格的框架拉

图三 sqlite3可视化操作

Item编辑:

# -*- coding: utf-8 -*-

import scrapy

class SanwenItem(scrapy.Item):

    title=scrapy.Field()

    time=scrapy.Field()

    author=scrapy.Field()

    url=scrapy.Field()

Pipeline编辑:

这部分内容是重点!现学现用。

# -*- coding: utf-8 -*-

import sqlite3

class SanwenPipeline(object):

    def open_spider(self,spider):  # 打开爬虫时要链接数据库

        self.con = sqlite3.connect("sanwen.sqlite")   # 链接数据库

        self.cu = self.con.cursor()   #产生一个新光标

    def process_item(self, item, spider):   # 处理item

        print(spider.name,'pipelines')   # 打印传送到管道的信息,看管道是否启用,可免去

        insert_sql="insert into sanwen(title,time,author,url) values('{}','{}','{}','{}')".format(item['title'],item['time'],item['author'],item['url'])   # item信息引入数据库的插入对象操作

        self.cu.execute(insert_sql)   # 执行插入操作

        self.con.commit()   # 提交操作

        return item   # 函数的返回值是item列表

    def spider_close(self,spider):   # 关闭爬虫时也关闭数据库链接

        self.con.close()

Settings编辑:

# -*- coding: utf-8 -*

BOT_NAME = 'sanwen'

SPIDER_MODULES = ['sanwen.spiders']

NEWSPIDER_MODULE = 'sanwen.spiders'

FEED_EXPORT_ENCODING = 'utf-8'   # 中文网页编码要加这句,防止输出乱码

ROBOTSTXT_OBEY = True

LOG_FILE='log.txt'   # 将原本终端中显示的日志信息打印到一个log.txt文本文件中,静默爬取

ITEM_PIPELINES = { 'sanwen.pipelines.SanwenPipeline': 300 }   # 启用自定义管道,后面的数字只要在1~2000即可,表示一个优先顺序

最后是sanwen_spider的编写:

# -*- coding: utf-8 -*-

import scrapy

from sanwen.items import SanwenItem

class SanwenSpiderSpider(scrapy.Spider):

    name = 'sanwen_spider'

    allowed_domains = ['sanwen.net']

    start_urls = ['https://www.sanwen.net/sanwen/']


    def parse(self,response):    # 主解析函数,用来产生翻页链接和对应请求响应的

        for i in range(1,11):   # 注意range(1,11)的取值是从1到10不包括11!

            yield scrapy.Request("https://www.sanwen.net/sanwen/?p=%s"%i,callback=self.parse_item)

            #上式发送请求,注意%i的变量替代用法,回调的函数是下面的item解析函数

    def parse_item(self,response):

        print(response)

        item=SanwenItem()

        lis=response.xpath('//div[@class="categorylist"]/ul/li')

        title_list=lis.xpath('h3/a[2]/text()').extract()

        time_list=lis.xpath('div/text()').re('\d{4}-\d{2}-\d{2}')

        author_list=lis.xpath('div/a/text()').extract()

        url_list=lis.xpath('h3/a[2]/@href').extract()

        new_url_list=[]

        # 爬取的相对链接产生绝对链接

        for url_data in url_list:

            new_url_list.append("https://www.sanwen.net"+url_data)

        for a,b,c,d in zip(title_list,time_list,author_list,new_url_list):   # 整合item到一起以便打印出来

            print(a,":",":",b,":",c,":",d)

            a=a.encode('utf-8')    # 没有这四句转码,爬取会出错,应该是中文编码引起的问题

            b=b.encode('utf-8')

            c=c.encode('utf-8')

            d=d.encode('utf-8')

            item["title"]=a

            item["time"]=b

            item["author"]=c

            item["url"]=d

            yield item

最后运行爬虫scrapy craw lsanwen_spider就可以在SQLiteStudio中刷新看到爬取结果了。

图四 爬取结果引入数据库结果

总的来说,编写该爬虫的过程中遇到许多问题,多数跟中文编码导致的错误相关。

对于Pipeline中的内容,打算照搬即可,所有引入数据库的操作基本相似。

像这样不需要cookies访问、也没有js控制的复杂操作的网页爬起来还是相对轻松的,一点体会。

你可能感兴趣的:(scrapy学习笔记(八))