美文网首页
Scrapy入门学习

Scrapy入门学习

作者: LZY_c44b | 来源:发表于2018-09-06 15:49 被阅读0次

简介

采用异步框架。
scrapy中文文档:
https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/overview.html#
优点:
使用框架可以自己完成log ,并发,存储,监控。
整体架构图:

Scrapy架构图
Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等

Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理,

Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),

Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)

Downloader Middlewares(下载中间件):可以当作是一个可以自定义扩展下载功能的组件

Spider Middlewares(Spider中间件):可以理解为是一个可以自定扩展和操作引擎和Spiders中间‘通信‘的功能组件(比如进入Spiders的Responses;和从Spiders出去的Requests)

数据流向:

1.引擎从调度器中取出一个链接(URL)用于接下来的抓取
2.引擎把URL封装成一个请求(Request)传给下载器
3.下载器把资源下载下来,并封装成应答包(Response)
4.爬虫解析Response
5.解析出实体(Item),则交给实体管道进行进一步的处理
6.解析出的是链接(URL),则把URL交给调度器等待抓取

新建工程

scrapy startproject projectName

这个命令会在当前目录下创建一个新目录projectName,此目录的结构如下:

│  scrapy.cfg
│
└─projectName
    │  items.py
    │  pipelines.py
    │  settings.py
    │  __init__.py
    │
    └─spiders
            __init__.py

scrapy.cfg: 项目配置文件
projectName/: 项目python模块, 呆会代码将从这里导入
projectName/items.py: 项目items文件
projectName/pipelines.py: 项目管道文件
projectName/settings.py: 项目配置文件
projectName/spiders: 放置spider的目录

定义Item

类名必须含有Item。
Items是将要装载抓取的数据的容器,在其中定义我们需要的数据。
例如:

class MyspiderItem(scrapy.Item):
       define the fields for your item here like:
       name = scrapy.Field()

每一项都是一个list,存储json时需使用dict函数转换item,有时也需要根据需求对item进行额外的转换然后存入json文件中。

json.dumps(dict(item), ensure_ascii=False)

新建爬虫

scrapy genspider [-t template] <name> <domain>

在当前文件夹或当前项目的spiders文件夹中创建一个新的爬虫。该<name>参数设置为爬虫的name(不能与project重复),而<domain>用于生成allowed_domains和start_urls爬虫的属性。
在spiders目录下生成文件:

<name>.py

运行爬虫

命令行方式:

scrapy crawl <name>

IDE方式,需要在项目的根目录(与scrapy.cfg同级)创建一个入口脚本:

from scrapy.cmdline import execute
execute(['scrapy', 'crawl', '<name>'])

这样能在IDE中运行调试。

编写注意

新建的爬虫文件中,会自动含有以下三个成员:

    name = '<name>'                                   #即新建爬虫的名字,在整个项目中有且只能有一个、名字不可重复
    allowed_domains = ['<name>.com']      
                                                      #这个不是必须的;但是在某写情况下需要用得到,
                                                      #比如使用爬取规则的时候就需要了;
                                                      #它的作用是只会跟进存在于allowed_domains中的URL。
                                                      #不存在的URL会被忽略。
    start_urls = [' ']                           #初始爬虫页面,根据需要进行调整

一般我们需要对url进行拼接,然后调用Request进行并发处理:

    def start_requests(self):
        for i in range(1, 10):
            url = self.start_urls[0] + str(i) + self.bashurl
            yield Request(url, self.parse)                     #scrapy的优点,并发处理多个url

生成的文件中会自包含一个类,这个类一般用作Request的回调函数,不要轻易改为他用:

    def parse(self, response):

scrapy使用的是自带的Selector配合XPath解析获取需要的数据,但也可以使用BeautifulSoup解析(相比Selector慢)。
XPath语法:
http://www.w3school.com.cn/xpath/xpath_syntax.asp
示例:

for content_url in Selector(text=index_html).xpath('//div[@class="list post-list"]')

导入item类时,需要加入路径,否则会一直提示找不到包,如下:

fpath = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
ffpath = os.path.abspath(os.path.join(fpath,".."))
sys.path.append(ffpath)
from mySpider.items import MyspiderItem

item的传递

yield Request(str(item["source_url"][0]), meta={'item': item}, callback=self.get_url_content)

有时item在一个页面无法获取完整,需要在另一个页面继续获取,这时需要就要通过上面的方法传递。
通过下面的方式取得传递的item:

def get_url_content(self, response):
        item = response.meta['item']
        #return item    # ×××  有时会需要保存多中item,处理完一个item,这时不能直接return,否则程序就结束了
        #yield item      # √√√   正确方式
        #yield Request(url, meta={'item': item, 'rdt': rdt, 'comments':cmt,
        #    'rewards':rewards,'total': total, 'curpage': cur}, callback=self.processNextItem)
        # 传递多个参数

区分不同的item

if isinstance(item, MyspiderItem):
    ...
else:
    ...

配置

在对应的setting文件中,可以进行一些配置。
设置pipeline,需要在pipelines.py文件中编写对应函数进行处理,可以编写存储为json文件,也可以编写MySql存储(需进行登录等配置)。
设置:

ITEM_PIPELINES = {
   'mySpider.pipelines.MyspiderPipeline': 300,
}

mySpider(项目目录).pipelines.MyspiderPipeline(其中定义的类) 后面的 300是优先级程度(1-1000随意设置,数值越低,组件的优先级越高)。
可根据需求定义多个类(存储为不同方式),设定不同的优先级。

其中pipelines自己生成的类中有一个函数process_item,其参数item和spider是不可改变的,主要也是对item进行处理:

 def process_item(self, item, spider):
         ···
         return item     # 这个返回值是必须的

注意存储文件时,可以事先打开一个文件,设定utf-8编码,因为Request得到的数据是unicode编码的。

def __init__(self):
        self.file = codecs.open('smzdm.json', 'w+', encoding='utf-8')

注意文件的默认保存目录是项目的根目录(与scrapy.cfg同级)

去重

有时会爬到重复的数据,需要进行去重后存放到文件或者数据库中。
通常做法可以在pipelines中加入去重类,然后在settings中调高其优先级便可以达到此效果,但是有一个缺点是这种方法是在获取完所有数据后才去重。
示例:

url_count = 0

class DuplicatesPipesline(object):
    def __init__(self):
        self.urls_seen = {}
        if os.path.exists("smzdm_dup.json"):
            self.urls_seen = json.loads(io.open("smzdm_dup.json", 'r', encoding='utf-8').read())
        #打开之前存储的去重数据文件

    def process_item(self, item, spider):
        global url_count
        url_count += 1
        if item["source_url"][0] in self.urls_seen:
            raise DropItem("Duplicate item found")     #丢弃掉重复数据
        else:
            self.urls_seen[item["source_url"][0]] = {}

            if url_count % 300 == 0:
                io.open("smzdm_dup.json", "w", encoding="utf-8").write(
                    json.dumps(self.urls_seen, indent=4, sort_keys=True, ensure_ascii=False))
            return item

    def __del__(self):
        if url_count:
            io.open("smzdm_dup.json", "w", encoding="utf-8").write(
                json.dumps(self.urls_seen, indent=4, sort_keys=True, ensure_ascii=False))

    # 最后将数据写入

配置优先级:

ITEM_PIPELINES = {
   'mySpider.pipelines.MyspiderPipeline': 300,
   'mySpider.pipelines.DuplicatesPipesline': 200,
}

相关文章

  • scrapy小记

    scrapy入门学习地图 scrapy 框架:http://doc.scrapy.org/en/latest/to...

  • 28.scrapy的入门使用

    scrapy的入门使用 学习目标: 掌握 scrapy的安装 应用 创建scrapy的项目 应用 创建scrapy...

  • scrapy 学习日记

    文章出处:【scrapy】学习Scrapy入门 整体结构 引擎(Scrapy Engine),用来处理整个系统的数...

  • Scrapy爬取猫眼电影并存入MongoDB数据库

    之前入门了Scrapy,用Scrapy框架爬取了豆瓣电影TOP250,最近打算学习下scrapy-redis分布式...

  • 【scrapy】学习Scrapy入门

    Scrapy介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信...

  • scrapy笔记

    1 scrapy的运行原理 参考:Learning Scrapy笔记(三)- Scrapy基础Scrapy爬虫入门...

  • Scrapy入门案例

    Scrapy入门案例 Scrapy教程: 官方 《Scrapy 1.5 documentation》 中文 《S...

  • Scrapy入门学习

    简介 采用异步框架。scrapy中文文档:https://scrapy-chs.readthedocs.io/zh...

  • 学习Scrapy入门

    Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化...

  • Scrapy学习(一)-爬取天气信息

    开始学习下scrapy这个爬虫框架,安装过程可以随便google,这里不再赘述 scrapy文档 这里面有个入门教...

网友评论

      本文标题:Scrapy入门学习

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