Advertisement

爬虫scrapy框架简单爬取一个网页

阅读量:

爬虫scrapy框架

scrapy流程图

在这里插入图片描述

开始一个scrapy项目

首先进入你想要使用的虚拟环境,键入

复制代码
    pip install scrapy

下载完成后再虚拟环境中键入

复制代码
    scrapy startproject 项目名称

在这里插入图片描述
即可以在当前所在路径创建一个scrapy项目

创建一个爬虫文件

首先进入我们的scrapy项目

复制代码
    cd 项目名

这里我选择直接用命令行生成爬虫文件

复制代码
    scrapy genspider 爬虫名 爬虫网页路径

在这里插入图片描述
现在我们新建了了一个爬虫文件

测试这个爬虫能不能爬到数据

同样的,我们可以用scrapy框架测试我们的项目

复制代码
    scrapy shell 爬虫网页路径

在这里插入图片描述
建立链接后键入

复制代码
    response.text

在这里插入图片描述
这里证明我们的链接可以获取到网页数据了

修改parse方法

现在我们回到pycharm中,看一下我们创建到的项目结构
在这里插入图片描述
版本原因可能有些scrapy版本不会自动创建middlewares,然后如果是python2.7的别忘记加utf-8编码格式
现在需要在项目中指定一下虚拟环境,这个和django差不多
在这里插入图片描述
现在我们的项目就不飘红了
我们在爬虫py文件中的parse方法中对返回到的值进行操作
先添加测试时候的代码

复制代码
    import scrapy
    
    
    class Gw2metabuildSpider(scrapy.Spider):
    name = 'GW2metabuild'
    allowed_domains = ['metabattle.com']
    start_urls = ['http://metabattle.com/']
    
    def parse(self, response):
        html_str=response.text
        print(html_str)

在命令行中运行这个爬虫

复制代码
    scrapy crawl 爬虫名

在这里插入图片描述
在这里插入图片描述
这是获取到值的结果
现在我们需要对网页进行分析,得到我们需要的数据
首先我选的这个网页是我玩的游戏guildwar2的国外攻略网站,相对于国内的网页来说可能比较简单,如果同样方法爬国内网页可能不行,这时候我们需要去把settings中的字段变一下。这在之后的博客中会详细的讲一讲,我先把这个实例跑完
现在我换一下metabuild中的raid内容,把网页复制下来,然后写到我们的start_urls中,注意这个start_urls可以为多个值的,但这次只用一个。

复制代码
    import scrapy
    
    
    class Gw2metabuildSpider(scrapy.Spider):
    name = 'GW2metabuild'
    allowed_domains = ['metabattle.com']
    start_urls = ['https://metabattle.com/wiki/Raid']
    
    def parse(self, response):
        html_str=response.text
        print(html_str)

重新在跑一次看看能不能获取到
现在,我需要在网页中拿下recommand职业的数据
这个网页其实比较简单,发送请求后的doc就是前端展示的完整网页了,所以只需要在element中通过xpath找到数据就可以直接在项目中用了
在这里插入图片描述
这里的recommand的xpath路径,我只取了其中职业类型的名字

复制代码
    //div[@class='build-card-c'][1]/div/div/div/span/a

我们在项目中测试一下找不找的到
修改代码为

复制代码
    import scrapy
    
    
    class Gw2metabuildSpider(scrapy.Spider):
    name = 'GW2metabuild'
    allowed_domains = ['metabattle.com']
    start_urls = ['https://metabattle.com/wiki/Raid']
    
    def parse(self, response):
        print('#############')
        node_list=response.selector.xpath("//div[@class='build-card-c'][1]/div/div/div/span/a/text()").extract()
        print(node_list)

重新跑一遍
在这里插入图片描述
找到了我们要的数据,这里是一个列表,逐条输出只要加个for遍历一下就可以了

修改item获取指定的字段

这里的item.py文件作用和django中的serializer有一定的相似之处,也是一个指定需要字段的方法
今天这部分还是没有详细的用到item的,所以只是简单的添加一条我们的职业名称,在item中加上一个filed就可以了
在这里插入图片描述
然后修改一下我们的爬虫,导入item并指定字段

复制代码
    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://docs.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    
    class Gw2Item(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    profession_name=scrapy.Field()
复制代码
    # -*- coding: utf-8 -*-
    import scrapy
    from GW2 import items
    
    
    class Gw2metabuildSpider(scrapy.Spider):
    name = 'GW2metabuild'
    allowed_domains = ['metabattle.com']
    start_urls = ['https://metabattle.com/wiki/Raid']
    
    def parse(self, response):
        print('#############')
        node_list=response.selector.xpath("//div[@class='build-card-c'][1]/div/div/div/span/a/text()").extract()
        print(node_list)
        item_list = []
        for i in node_list:
            item=items.Gw2Item()
            item['profession_name']=i
            item_list.append(item)
        return item_list

这里代码有点冗余,毕竟我之找了一个字段信息,如果是多个字段就不能这样写了,现在我们把这个数据保存成csv文件,只需要在环境下键入

复制代码
    scrapy crawl 爬虫名 -o 文件名.csv

即可,结果如图
在这里插入图片描述

链接数据库

现在我们来改pipelines中的内容

复制代码
    import pymongo
    
    class Gw2Pipeline(object):
    def __init__(self):
        self.client=pymongo.MongoClient(host='localhost',port=27017)
        self.db=self.client['GW2_raid_metabuild']
    def process_item(self, item, spider):
        self.db.profession_name.insert(item)
        print('enter process_item ##########')
        return item

关于pipeline类,我们可以创建无数个pipeline类,但是每个pipelines类必须实现一个process_item方法,这个方法会自动返回一个item,这个返回值是用来给下一个pipeline类进行数据筛选的。
为了链接数据库,我们可以在调用类的时候进行链接,也可以在爬虫开始的时候进行链接,我这里是调用类的时候链接,如果想要在爬虫开始的时候链接,我们可以在下面这个方法中添加数据库的链接

复制代码
    这个是pipeline类中的方法
    def open_spider(self,spider):

二级链接

为了获取从开始的页面中包含的url信息并给这个url发送信息,我们需要用到scrapy.Request方法
改写我们的爬虫文件为

复制代码
    # -*- coding: utf-8 -*-
    import scrapy
    from GW2 import items
    
    
    class Gw2metabuildSpider(scrapy.Spider):
    name = 'GW2metabuild'
    allowed_domains = ['metabattle.com']
    start_urls = ['https://metabattle.com/wiki/Raid']
    
    def parse(self, response):
    这里获取了一个网页中包含的url信息
        href=response.selector.xpath('//*[@id="mw-content-text"]/div/div[3]/div[1]/div[1]/div[2]/span/a/@href').extract_first()
        将url拼接成可以使用的完整的url
        url='https://'+self.allowed_domains[0]+href
       	往items中添加字段,注意要在items.py中注册这个字段
        item=items.Gw2Item()
        item['second_url']=url
        往新的链接发送请求
        yield scrapy.Request(url=url,meta={'meta':item},callback=self.Zerksite)
    	新页面处理函数
    def Zerksite(self,response):
    		拿出其中的部分内容
        overview=response.selector.xpath('//*[@id="mw-content-text"]/div/dl/dd/text()').extract()
        print(overview)
        将之前Request方法中传递的item类取出
        item=response.meta['meta']
        将新的字段添加到item,同样的,需要在items.py中注册字段
        item['overview']=overview
        print(item)
        抛出item
        yield item

修改我们的pipelines

复制代码
    # -*- coding: utf-8 -*-
    
    # 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
    import pymongo
    
    class Gw2Pipeline(object):
    def __init__(self):
        self.client=pymongo.MongoClient(host='localhost',port=27017)
        self.db=self.client['GW2_raid_metabuild']
    def process_item(self, item, spider):
        self.db.overview.insert(dict(item))
        print('enter process_item ##########')
        return item

现在跑一次crawl
在这里插入图片描述
查看数据库
在这里插入图片描述
获取成功

scrapy-redis分布爬虫

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~