美文网首页职业成长之路
爬虫入门(5)-Scrapy使用Request访问子网页

爬虫入门(5)-Scrapy使用Request访问子网页

作者: Maxim_Tian | 来源:发表于2017-05-17 20:18 被阅读1283次

    Scrapy中的Request函数可以用来抓取访问子网页的信息。
    用法类似如下形式

        yield Request(['url'], callback=self.<yourfunction>)
    

    需要注意的是Request函数前面需要加上yield
    关于关键字yield的介绍可以参考这篇博客(初学者比较好理解):

    http://www.cnblogs.com/fydd/p/4546012.html

    抓取的网站

    我的目标从盗墓笔记系列的每一本抓取它的章节名称。

    在items.py中声明抓取的信息

    scrapy框架中items.py的代码如下:

    # -*- coding: utf-8 -*-
    
    import scrapy
    
    class DaomubijiItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        bookOrder = scrapy.Field() # 书编号
        bookName = scrapy.Field() # 书标题
        chapterFirst = scrapy.Field() # 章节类别
        chapterMid = scrapy.Field() # 章节序号
        chapterLast = scrapy.Field()  # 章节名称
    

    在Scrapy中使用MongoDB

    Scrapy中使用MongoDB需要在settings.py中定义接口变量

    # -*- coding: utf-8 -*-
    
    BOT_NAME = 'daomubiji'
    
    SPIDER_MODULES = ['daomubiji.spiders']
    NEWSPIDER_MODULE = 'daomubiji.spiders'
    
    ITEM_PIPELINES = {
        'daomubiji.pipelines.DaomubijiPipeline': 300 # 数字代表这个管道的优先级,取0-1000之间的任意一个数即可
    }
    
    USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'
    COOKIES_ENABLED = True
    
    MONGODB_HOST = '127.0.0.1'
    MONGODB_PORT = 27017
    MONGODB_DBNAME = 'Mydaomubiji'
    MONGODB_DOCNAME = 'daomubiji'
    

    这里我定义的数据库名称为:“Mydaomubiji”;数据库表名为:"daomubiji"

    接着我们在pipelines.py调用接口,代码如下:

    from items import DaomubijiItem
    from scrapy.conf import settings
    import pymongo
    
    
    class DaomubijiPipeline(object):
        def __init__(self):
            host = settings['MONGODB_HOST']
            port = settings['MONGODB_PORT']
            dbName = settings['MONGODB_DBNAME']
            client = pymongo.MongoClient(host=host, port=port)
            tdb = client[dbName]
            self.post = tdb[settings['MONGODB_DOCNAME']]
    
        def process_item(self, item, spider):
            bookInfo = dict(item)
            self.post.insert(bookInfo)
            return item
    
    

    网页信息抓取代码

    #-*_coding:utf8-*-
    
    import scrapy
    from scrapy.spiders import Spider
    from scrapy.selector import Selector
    from scrapy.http import Request
    from daomubiji.items import DaomubijiItem
    
    class daomubijiSpider(Spider):
        name = "daomubijiSpider"
        start_urls = ['http://www.daomubiji.com/']
    
        def parse_detail(self,response): # 提取子网页信息
            selector = Selector(response)
            item = DaomubijiItem()
    
            book_order_name = selector.xpath('//h1/text()').extract()[0]
            pos = book_order_name.find(u':')
            book_order = book_order_name[:pos] # 获取书编号
            book_name = book_order_name[pos + 1:] # 获取书名
    
            chapter_list = selector.xpath('//article[@class="excerpt excerpt-c3"]//text()').extract()
            for each in chapter_list:
                pos_first = each.find(' ')
                pos_last = each.rfind(' ')
                chapter_first = ''
                chapter_mid = ''
                chapter_last = ''
                if pos_first != pos_last:
                    chapter_first = each[:pos_first]
                    chapter_mid = each[(pos_first + 1): pos_last]
                    chapter_last = each[pos_last + 1:]
                else:
                    chapter_first = each[:pos_first]
                    chapter_last = each[pos_last + 1:]
    
                # 存储信息
                item['bookOrder'] = book_order
                item['bookName'] = book_name
                item['chapterFirst'] = chapter_first
                item['chapterMid'] = chapter_mid
                item['chapterLast'] = chapter_last
                yield item
    
        def parse(self, response): # 程序从这个函数开始执行
            selector = Selector(response)
    
            book_filed = selector.xpath('//article/div') # 抓取书标题
    
            book_link = selector.xpath('//article/p/a/@href').extract() # 抓取盗墓笔记每本书的链接
            # '//article/p/a/@href'也可以写成('//article//@href')
    
            link_flag = 0
            for each in book_filed:
                book_name_title = each.xpath('h2/text()').extract()[0]
                pos = book_name_title.find(u':')
                if pos == -1: # 只抓取符合我们格式规定的书
                    continue
                yield Request(book_link[link_flag], callback=self.parse_detail) # 调用parse_detail函数
                link_flag += 1
    
    

    网页抓取xpath路径就不作解释了,主要看一下子网页信息的抓取过程
    book_link中的信息为:

    每一条url都存放在book_link列表。
    在子网页中,我们需要提取每一章的名称,对它的处理定义在parse_detail函数。
    最后在parse函数中使用Request便可实现对parse_detail的调用。Request中的callback=后面加上所需调用的函数名。
    当然我们在某些时候访问类似的页面时可以调用parse本身,这样子就像一个递归函数,类似如下:

    yield Request(nextLink,callback=self.parse)

    比如访问"豆瓣电影250"网站时,爬虫将从第一页自动爬取到最后一页,而不需要我们那手动设置访问页码。

    运行结果

    爬取的信息存在mongoDB中,Ubuntu下使用Robomongo可视化工具查看的结果如下:

    从上面可以看到我们成功抓取了盗墓笔记每一本书的章节信息
    另外由于没有排序所以数据库的信息所以看起来比较乱。

    附上代码链接:

    https://github.com/MaximTian/Daomubiji_Scrapy/tree/master

    就写到这里了

    好好学习天天向上~

    相关文章

      网友评论

        本文标题:爬虫入门(5)-Scrapy使用Request访问子网页

        本文链接:https://www.haomeiwen.com/subject/pdzdxxtx.html