Scrapy框架初级篇

1.概念:scrapy。框架。  Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。2.安装:Linux:

pip3 install scrapy

  Windows:      a. pip3 install wheel      b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted      c. 进入下载目录,执行 pip3 install Twisted?17.1.0?cp35?cp35m?win_amd64.whl      d. pip3 install pywin32      e. pip3 install scrapy

3.创建工程:scrapy startprroject proName4.创建爬虫文件:scrapy genspider fileName xxx.com5.执行爬虫文件:scrapy crawl name6.持久化操作:    1.scrapy crawl name -o file.xxx    2.pipeline:        1.获取解析内容        2.创建item对象,将解析内容存储到item对象中(items类中进行相应属性的声明(scrapy.Filed()))        3.yiled关键字将item提交给管道文件        4.管道文件负责接收item对象,进行持久化操作        5.settings中开启管道

scrapy 不需要考虑session&cookie的问题

firstblood 初识scrapy

# -*- coding: utf-8 -*-
import scrapy

class FirsttestSpider(scrapy.Spider):#爬虫类是基于Spider这个父类
    name = ‘firstTest‘ #爬虫文件的名称
    #允许的域名:
    #allowed_domains = [‘www.qiushibaike.com‘]
    #起始url列表:当前的爬虫文件可以从该列表中存储的url中爬取数据
    start_urls = [‘https://www.qiushibaike.com/text/‘]

    #继承与父类的方法:用于解析请求到的页面数据
    def parse(self, response):
        print(‘haha this is  hehe‘)
        print(response)
        #xpath函数的返回值是Selector对象(使用xpath表达式解析出来的内容是被存储在了Selecotr对象中)
        #title = response.xpath(‘//*[@id="qiushi_tag_121076506"]/div[1]/a[2]/h2/text()‘)[0].extract()
        #extract系列函数的作用是将Selector中的文本数据取出。
        #Selector对象可以直接调用xpath函数。
        title = response.xpath(‘//*[@id="qiushi_tag_121056271"]/div[1]/a[2]/h2/text()‘).extract_first()
        title = response.xpath(‘//*[@id="qiushi_tag_121056271"]/div[1]/a[2]/h2/text()‘)[0]
        print(title)

firstTest.py

修改内容及其结果如下:
19行:USER_AGENT = ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36‘ #伪装请求载体身份

22行:ROBOTSTXT_OBEY = False  #可以忽略或者不遵守robots协议

settings.py

qiubai   基础+持久化

# -*- coding: utf-8 -*-
import scrapy
from qiubai.items import QiubaiItem

class QiubaitestSpider(scrapy.Spider):
    name = ‘qiubaiTest‘
    #allowed_domains = [‘www.qiushibaike.com/text‘]
    start_urls = [‘http://www.qiushibaike.com/text/‘]

    def parse(self, response): #返回值类型必须为None 或者迭代器类型
        div_list = response.xpath(‘//div[@id="content-left"]/div‘)#该列表中存储的元素为Selecoter对象
        content_list = []
        for div in div_list:
            #step 1
            author = div.xpath(‘.//h2/text()‘).extract_first()
            content = div.xpath(‘.//div[@class="content"]/span[1]//text()‘).extract_first()

            #使用管道进行持久化存储的流程:
                #1.使用爬虫文件获得解析到的数据
                #2.将解析到的数据封装存储到items对象中
                #3.将封装好的items对象提交给管道文件
                #4.在管道文件中编写持久化存储的代码
                #5.在settings中开启管道
            # step 2
            item = QiubaiItem() #创建items对象
            item[‘author‘] = author
            item[‘content‘] = content

            #step 3:
            yield item

qiubaiTest.py

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

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class QiubaiItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author = scrapy.Field()
    content = scrapy.Field()

items.py

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

# Define your item pipelines here
#
# Don‘t forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

class QiubaiPipeline(object):
    def __init__(self):
        self.fp = None

    #该函数在整个爬虫过程中只会被执行一次:开始进行爬虫时被调用
    def open_spider(self,spider):
        print(‘开始爬取数据‘)
        self.fp = open(‘./qiubaiText.txt‘,‘w‘,encoding=‘utf-8‘)
    #该函数作用:当爬虫文件中,通过yiled每向管道中提交一次items,该函数就会被执行一次。
    def process_item(self, item, spider):
        print(‘向文件中写入了一条数据!‘)
        self.fp.write(item[‘author‘]+‘:‘+item[‘content‘]+"\n\n\n")
        return item
    # 该函数在整个爬虫过程中只会被执行一次:结束爬虫的时候被调用
    def close_spider(self,spider):
        self.fp.close()
        print(‘结束爬取数据‘)

pipelines.py

#修改部分

USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36‘

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

ITEM_PIPELINES = {
    ‘qiubai.pipelines.QiubaiPipeline‘: 300,
}

settings.py

qiubai_all    基础+持久化+分页

# -*- coding: utf-8 -*-
import scrapy
from qiubai_all.items import QiubaiAllItem

class QiutuSpider(scrapy.Spider):
    name = ‘qiutu‘
    #allowed_domains = [‘www.qiushibaike.com/pic/‘]
    start_urls = [‘http://www.qiushibaike.com/pic/‘]

    #指定一个页码通用的url
    url = ‘https://www.qiushibaike.com/pic/page/%d/?s=5127014‘
    pageNum = 1 #控制页码

    def parse(self, response):
        div_list = response.xpath(‘//*[@id="content-left"]/div‘)
        for div in div_list:
            item = QiubaiAllItem() #创建item对象
            item[‘author‘]=div.xpath(‘.//h2/text()‘).extract_first()
            item[‘content‘]=div.xpath(‘.//div[@class="content"]/span/text()‘).extract_first()

            yield item

        #想要对应不同页码的url发起请求
        if self.pageNum <= 35:
            self.pageNum += 1 #从第二页发起请求

            print(‘开始爬取第%d页的数据‘%self.pageNum)

            new_url = format(self.url%self.pageNum) #是新页码的url
            #发起请求
            #url:请求的url
            #callback:回调函数(指定解析数据的规则)
            yield scrapy.Request(url=new_url,callback=self.parse)

qiutu.py

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

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class QiubaiAllItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author = scrapy.Field()
    content = scrapy.Field()

items.py

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

# Define your item pipelines here
#
# Don‘t forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

class QiubaiAllPipeline(object):
    def __init__(self):
        self.fp = None
    def open_spider(self,spider):
        print(‘开始爬虫‘)
        self.fp = open(‘./data.txt‘,‘w‘,encoding=‘utf-8‘)

    def process_item(self, item, spider):
        #1.获取item中的数据
        self.fp.write(item[‘author‘]+‘:‘+item[‘content‘]+‘\n\n‘)
        return item

    def close_spider(self,spider):
        print(‘爬虫结束‘)
        self.fp.close()

pipelines.py

ROBOTSTXT_OBEY = False

USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36‘

ITEM_PIPELINES = {
    ‘qiubai_all.pipelines.QiubaiAllPipeline‘: 300,
}

settings.py

校花网 图片 分页

# -*- coding: utf-8 -*-
import scrapy
from xiaohuaPro.items import XiaohuaproItem

class XiaohuaSpider(scrapy.Spider):
    name = ‘xiaohua‘
    #allowed_domains = [‘www.521609.com/daxuemeinv‘]
    start_urls = [‘http://www.521609.com/daxuemeinv/‘]
    url = ‘http://www.521609.com/daxuemeinv/list8%d.html‘
    page_num = 1
    def parse(self, response):
        li_list = response.xpath(‘//*[@id="content"]/div[2]/div[2]/ul/li‘)
        for li in li_list:
            item = XiaohuaproItem()
            item[‘img_url‘] = li.xpath(‘./a/img/@src‘).extract_first()
            item[‘img_url‘] = ‘http://www.521609.com‘+item[‘img_url‘]
            item[‘img_name‘] = li.xpath(‘./a/img/@alt‘).extract_first()

            yield item
        if self.page_num <= 23:
            self.page_num += 1
            url = format(self.url%self.page_num)
            yield scrapy.Request(url=url,callback=self.parse)

xiaohua.py

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

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class XiaohuaproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    img_url = scrapy.Field()
    img_name = scrapy.Field()

items.py

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

# Define your item pipelines here
#
# Don‘t forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json
import urllib.request
import os
class XiaohuaproPipeline(object):
    def __init__(self):
        self.fp = None
    def open_spider(self,spider):
        print(‘开始爬虫‘)
        self.fp = open(‘./data.json‘,‘w‘,encoding=‘utf-8‘)
    def process_item(self, item, spider):
        img_dic = {
            ‘img_url‘:item[‘img_url‘],
            ‘img_name‘:item[‘img_name‘]
        }
        json_string = json.dumps(img_dic,ensure_ascii=False)
        self.fp.write(json_string)

        #下载图片操作
        if not os.path.exists(‘xiaohua‘):
            os.mkdir(‘xiaohua‘)
        filePath=‘xiaohua/‘+item[‘img_name‘]+‘.png‘
        urllib.request.urlretrieve(url=item[‘img_url‘],filename=filePath)
        print(filePath+ ‘:下载成功‘)

        return item
    def close_spider(self,spider):
        self.fp.close()
        print(‘爬虫结束‘)

pilelines.py

ROBOTSTXT_OBEY = False
USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36‘

ITEM_PIPELINES = {
    ‘xiaohuaPro.pipelines.XiaohuaproPipeline‘: 300,
}

settings.py

post请求 百度翻译

# -*- coding: utf-8 -*-
import scrapy

class PostdemoSpider(scrapy.Spider):
    name = ‘postDemo‘
    allowed_domains = [‘https://fanyi.baidu.com/sug‘]
    #start_urls = [‘http://https://fanyi.baidu.com/sug/‘]

    #该方法就是对start_urls列表中的url发起请求
    #def start_requests(self):  #父类对该方法的默认实现
        #for url in self.start_urls:
            #yield scrapy.Request(url=url,callback=parse)

    #重写父类的start_requests方法:该方法默认发起的是get请求
    def start_requests(self):
        post_url = ‘https://fanyi.baidu.com/sug/‘
        data = {
            ‘kw‘:‘dog‘
        }
        #FormRequest该函数用来发起post请求
        #Request使用用来发起get请求
        yield scrapy.FormRequest(url=post_url,formdata=data,callback=self.parse)

    def parse(self, response):
        print(response.text)

postDemo.py

ROBOTSTXT_OBEY = False
USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36‘

settings.py

scrapy组件介绍,流程分析

    • 引擎(Scrapy)
      用来处理整个系统的数据流处理, 触发事务(框架核心)
    • 调度器(Scheduler)
      用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
    • 下载器(Downloader)
      用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
    • 爬虫(Spiders)
      爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
    • 项目管道(Pipeline)
      负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

     * 解释:引擎首先会将爬虫文件中的起始url获取,并且提交到调度器中。如果需要从url中下载数据,则调度器会将url通过引擎提交给下载器,下载器根据url去下载指定内容(响应体)。下载好的数据会通过引擎移交给爬虫文件,爬虫文件可以将下载的数据进行指定格式的解析。如果解析出的数据需要进行持久化存储,则爬虫文件会将解析好的数据通过引擎移交给管道进行持久化存储。

如果最终需要将爬取到的数据值一份存储到磁盘文件,一份存储到数据库中,则应该如何操作scrapy?

答:

管道文件中的代码为:

#该类为管道类,该类中的process_item方法是用来实现持久化存储操作的。
class DoublekillPipeline(object):

    def process_item(self, item, spider):
        #持久化操作代码 (方式1:写入磁盘文件)
        return item

#如果想实现另一种形式的持久化操作,则可以再定制一个管道类:
class DoublekillPipeline_db(object):

    def process_item(self, item, spider):
        #持久化操作代码 (方式1:写入数据库)
        return item

pipelines.py

在settings.py开启管道操作代码为:

#下列结构为字典,字典中的键值表示的是即将被启用执行的管道文件和其执行的优先级。
ITEM_PIPELINES = {
   ‘doublekill.pipelines.DoublekillPipeline‘: 300,
    ‘doublekill.pipelines.DoublekillPipeline_db‘: 200,
}

#上述代码中,字典中的两组键值分别表示会执行管道文件中对应的两个管道类中的process_item方法,实现两种不同形式的持久化操作。

settings.py

原文地址:https://www.cnblogs.com/xujinjin18/p/9720973.html

时间: 2024-08-02 09:55:00

Scrapy框架初级篇的相关文章

scrapy框架初级

scrapy入门教程:https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html 一.安装 python模块网站,应用文件放置在scrips下,whl:https://www.lfd.uci.edu/~gohlke/pythonlibs/ Scrapy框架依赖 Twistid需要再上边网站下载,放置scrips下: ??pip install C:\python\Anaconda3\Twisted-18.7.0-cp36-cp

基于Python接口自动化测试框架(初级篇)附源码

引言 很多人都知道,目前市场上很多自动化测试工具,比如:Jmeter,Postman,TestLink等,还有一些自动化测试平台,那为啥还要开发接口自动化测试框架呢?相同之处就不说了,先说一下工具的局限性: 1.测试数据不可控:    接口虽然是对业务逻辑.程序代码的测试,而实际上是对数据的测试,调用接口输入一批数据,通过断言代码验证接口返回的数据,整个过程围绕数据测试.    如果返回的数据不是固定的,是变化的,那么断言失败,就无法知道是接口程序错误引起的,还是数据变化引起的,所以就需要进行测

Python爬虫进阶三之Scrapy框架安装配置

初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此整理如下. Windows 平台: 我的系统是 Win7,首先,你要有Python,我用的是2.7.7版本,Python3相仿,只是一些源文件不同. 官网文档:http://doc.scrapy.org/en/latest/intro/install.html,最权威哒,下面是我的亲身体验过程. 1.安装Python 安装过程我就不多说啦,我的电

内存泄露之常见问题解决--初级篇

身为一个段子猿,我决定来写写最近的学习心得. 1.简介 在整个Android开发过程中,内存泄露是导致OOM的一个重点因素.大概意思就是:GC无法回收原本应该被回收的对象,这个对象就引发了内存泄露.那有什么危害呢?手机的内存大小是有限的,如果不能释放的话,你就无法创建新的对象,你的新界面等等就无法正常运行,然后程序就OOM了(OutOfMemory). 2.OOM以及内存泄露 OOM通俗点讲就是,你家里有2个厕所,本来你和你老婆用的话,都是够用的,有一天你不小心造人了,从此家里有了1+1=3个人

(转)25个增强iOS应用程序性能的提示和技巧--初级篇

(转)25个增强iOS应用程序性能的提示和技巧--初级篇 本文转自:http://www.cocoachina.com/newbie/tutorial/2013/0408/5952.html 在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好的性能,是很困难的.在开发过程中,有许多事项需要记住,并且关于性能影响很容易就忘记. 本文收集了25个关于可以提升程序性能的提示和技巧,把

ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇(转)

ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇 阅读目录 ASP.NET Identity 前世今生 建立 ASP.NET Identity 使用ASP.NET Identity ASP.NET Identity 其他API介绍 小节 在之前的文章中,我为大家介绍了OWIN和Katana,有了对它们的基本了解后,才能更好的去学习ASP.NET Identity,因为它已经对OWIN 有了良好的集成. 在这篇文章中,我主要关注ASP.NET Identity的建

【Java】在Eclipse中使用JUnit4进行单元测试(初级篇)

本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数都完全正确,因为如果我们今后如果对程序进行扩展,用到了某个函数的其他功能,而这个功能有bug的话,那绝对是一件非常郁闷的事情.所以说,每编写完一个函数之后,都应该对这个函数

25个增强iOS应用程序性能的提示和技巧(初级篇)

25个增强iOS应用程序性能的提示和技巧(初级篇) 标签: ios内存管理性能优化 2013-12-13 10:53 916人阅读 评论(0) 收藏 举报  分类: IPhone开发高级系列(34)  在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好 “” 阅读器 在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致

在Eclipse中使用JUnit4进行单元测试(初级篇)【转】

来自[http://blog.csdn.net/andycpp/article/details/1327147] 本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数都完全正确,因为如果我们今后如果对程序进行扩展,用到了某个