美文网首页
Scrapy的使用方法

Scrapy的使用方法

作者: 时光清浅_许你心安_ | 来源:发表于2019-01-05 14:48 被阅读0次

    Scrapy框架

    什么是scrapy

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取。

    文件目录

    scrapy.cfg    #项目的配置文件
    items.py      #提取要爬取的字段,字典保存爬取到的数据的容器
    middlewares   #自定义中间件的地方
    pipelines.py  #管道,保存数据
    settings.py   #项目的设置文件 设置文件,UA,启动管道
    spiders       #存储爬虫代码目录
        itcast.py   #写爬虫的文件
    

    爬虫步骤:

    1.创建一个scrapy项目
    scrapy startproject mySpider   #mySpider是项目名字
    
    2.生成一个爬虫
    scrapy genspider itcast itcast.cn  #itcast是爬虫名字,"itcast.cn"限制爬虫地址,防止爬到其他网站
    
    3.提取数据
    完善spiders,使用xpath等方法
    
    4.启动爬虫
    scrapy crawl 爬虫名字    #crawl(抓取的意思)
    
    image.png

    spider内容

    spider翻页

    # -*- coding: utf-8 -*-
    import scrapy
    #导入items
    from tencent.items import TencentItem
    
    #自定义spider类,继承自scrapy.Spider
    class ItcastSpider(scrapy.Spider):
        name = 'itcast' #爬虫名字<爬虫启动时候使用:scrapy crawl itcast>
        #允许爬取的范围,防止爬虫爬到了别的网站
        allowed_domains = ['tencent.com']
        #开始爬取的地址,下载中间件提取网页数据
        start_urls = ['https://hr.tencent.com/position.php']
        #数据提取方法,接收下载中间件传过来的response(响应)
        def parse(self, response):
            #处理start_url地址对应的响应
            #提取数据
            # reti = response.xpath("//div[@class='tea_con']//h3/text()").extract()
            # print(reti)
    
            #分组,[1:-1]切片,不要第一条数据
            li_list = response.xpath("//table[@class="tablelist"]/tr")[1:-1]
            for li in li_list:
                #在item中定义要爬取的字段,以字典形式传入
                item = TencentItem()
                item["name"] = li.xpath(".//h3/text()").extract_first()
                item["title"] = li.xpath(".//h4/text()").extract_first()
                #yield可以返回request对象,BaseItem(items.py中的类),dict,None
                yield item  #yield传到pipeline
            #找到下一页url地址
            next_url = response.xpath('//a[@id="next"]/@href').extract_first()
            #如果url地址的href="地址"不等于javascript:;
            if next_url != "javascript:;":
                next_url = "https://hr.tencent.com/"+ next_url
                #把next_url的地址通过回调函数callback交给parse方法处理
                yield scrapy.Request(next_url,callback=self.parse)
    

    爬取详细页和翻页

    # -*- coding: utf-8 -*-
    import scrapy
    from yangguang.items import YangguangItem
    
    class YgSpider(scrapy.Spider):
        name = 'yg'
        allowed_domains = ['sun0769.com']
        start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type=4&page=0']
    
        def parse(self, response):
            tr_list = response.xpath("//div[@class='greyframe']/table[2]/tr/td/table/tr")
            for tr in tr_list:
                item = YangguangItem()
                item["title"] = tr.xpath("./td[2]/a[@class='news14']/@title").extract_first()
                item["href"] = tr.xpath("./td[2]/a[@class='news14']/@href").extract_first()
                item["publish_date"] = tr.xpath("./td[last()]/text()").extract_first()
                #执行进入url地址,再把item传到下面parse_detail,提取详细页的内容
                yield scrapy.Request(item["href"],callback=self.parse_detail,meta={"item":item})
            #翻页
            #获取url地址
            next_url = response.xpath("//a[text()='>']/@href").extract_first()
            #如果下一页url地址不为空,进入下一页连接
            if next_url is not None:
                yield scrapy.Request(next_url,callback=self.parse)
    
        #处理详情页
        def parse_detail(self,response):
            #item接收meta传过来的item,在item字典里继续为item添加内容
            item = response.meta["item"]
            #拿到详细页的内容
            item["content"] = response.xpath("//div[@class='c1 text14_2']//text()").extract()
            #拿到详细页的图片地址
            item["content_img"] = response.xpath("//div[@class='c1 text14_2']//img/@src").extract()
            #给图片前面加上http://wz.sun0769.com
            item["content_img"] = ["http://wz.sun0769.com" + i for i in item["content_img"]]
            #把item传给pipeline
            yield item
    

    items(存储爬取字段)

    import scrapy
    #scrapy.Item是一个字典
    class TencentItem(scrapy.Item):
    #scrapy.Field()是一个字典
    url = scrapy.Field()
    name = scrapy.Field()
    

    使用pipeline(管道)

    from demo1 import settings
    import pymongo
    
    class Demo1Pipeline(object):
        def __init__(self):
            #连接mongodb数据库(数据库地址,端口号,数据库)
            client = pymongo.MongoClient(host=settings.MONGODB_HOST, port=settings.MONGODB_PORT)
            #选择数据库和集合
            self.db = client[settings.MONGODB_DBNAME][settings.MONGODB_DOCNAME]
        def process_item(self, item, spider):
            data = dict(item)
            self.db.insert(data)
    
    #完成pipeline代码后,需要在setting中设置开启
    ITEM_PIPELINES = {
      #开启管道,可以设置多个管道,'管道地址数值':越小越先执行
      'mySpider.pipelines.MyspiderPipeline': 300,
    }
    # MONGODB 主机环回地址127.0.0.1
    MONGODB_HOST = '127.0.0.1'
    # 端口号,默认是27017
    MONGODB_PORT = 27017
    # 设置数据库名称
    MONGODB_DBNAME = 'DouBan'
    # 存放本次数据的表名称
    MONGODB_DOCNAME = 'DouBanMovies'
    
    注意
    • pipeline中process_item方法名不能修改,修改会报错
    • pipeline(管道)可以有多个
    • 设置了pipelines必须开启管道,权重越小优先级越高

    把数据保存到mongodb中

    #导入mongodb的包
    from pymongo import MongoClient
    #实例化client,建立连接
    client = MongoClient(host='127.0.0.1',port = 27017)
    #选择数据库和集合
    collection = client["tencent"]["hr"]
    
    class TencentPipeline(object):
        def process_item(self, item, spider):
            #传过来的数据是对象,把item转化为字典
            item = dict(item)
            #把数据存入mongodb数据库
            collection.insert(item)
            print(item)
            return item
    

    相关文章

      网友评论

          本文标题:Scrapy的使用方法

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