zoukankan      html  css  js  c++  java
  • Python爬虫框架Scrapy

    Scrapy是一个流行的Python爬虫框架, 用途广泛.

    使用pip安装scrapy:

    pip install scrapy
    

    scrapy由一下几个主要组件组成:

    • scheduler: 调度器, 决定下一个要抓取的url, 核心是一个任务队列

    • scrapy engine: 引擎, 用于控制整个系统的任务和数据流

    • downloader: 下载器, 下载目标url的内容并交给spider处理

    • spider: 爬虫, 用于分析下载内容, 提取数据项(item)包括获取要继续爬取的url.

    • pipeline: 项管道, 接受spider获得item并进行处理.

    • downloader middleware: 下载器中间件, 处理engine与downloader之间的请求响应

    • spider middleware: 爬虫中间件, 处理engine与spider之间的数据流

    • scheduler middleware: 调度器中间件, 处理engine与scheduler之间的数据流

    首先engine从scheduler中获得一项任务(url), 并将其封装为一个请求(request)交给downloader.

    downloader下载链接内容, 封装为响应(response)交给spider,spider获得item交给pipeline进行处理, 并将需要继续爬取的url交给scheduler.

    scrapy使用twisted提供的网络IO异步支持, 性能出色.

    第一个Scrapy爬虫

    在实际编写爬虫之前,首先要建立一个项目. 在项目目录的父目录中执行命令:

    scrapy startproject ScrapyDemo
    

    建立一个名为ScrapyDemo的项目, 目录结构如下:

    |- scrapy.cfg
    |- ScrapyDemo
    	|- __init__.py
        |- items.py
        |- pipelines.py
        |- settings.py
        |- spiders
        	|- __init__.py
    

    spider用于解析页面内容, 生成item.

    在spiders包下建立python脚本MySpider:

    from scrapy import Spider
    
    
    class MySpider(Spider):
        name = "cnblogs"
        allowed_domains = ["cnblogs.com"]
        start_urls = [
            "http://www.cnblogs.com/Finley/",
        ]
    
        def parse(self, response):
            filename = response.url.split("/")[-2]
            with open(filename, 'wb') as f:
                f.write(response.body)
    

    重写Spider类需要定义几个必须的成员:

    • name: spider的名字, 必须是唯一的

    • start_urls: 起始的url, 爬取时首先从该列表中开始爬取.从这些页面中得到的复合要求的url将被添加到队列中.

    • parse(): 负责解析downloader得到的response, 得到items交给pipeline处理.当然上述示例中只是保存了爬取的内容.

    parse方法是spider的核心, parse方法可以yield或返回两类对象:

    • scrapy.item.Item: item实例将被送入Pipeline进行处理

    • scrapy.Request: 请求将加入任务队列, 常用于爬取页内链接

    在项目根目录中执行命令开始爬取:

    scrapy crawl cnblogs
    

    使用selector分析内容

    在spider.parse中使用选择器(selector)来解析html(xml), selector采用XPath表达式来选择XML中的元素.

        def parse(self, response):
            for e in response.xpath('//ul/li'):
                title = e.xpath('a/text()').extract()
                link = e.xpath('a/@href').extract()
                desc = e.xpath('text()').extract()
                print title, link, desc
    

    选择器提供了四个方法:

    • xpath(pattern): 通过xpath选择元素

    • css(pattern): 通过css选择元素

    • extract(): 从元素中提取内容字符串

    • re(pattern): 使用正则表达式提取内容, 返回匹配的字符串

    常用xpath表达式:

    • 'html/head/title' 选择HTML文档中<head>标签内的<title>元素

    • '/html/head/title/text()': 选择<title>元素内的文本

    • '//div' 选择所有<div>元素

    • '//div[@class="panel"]' 选取class属性panel的<div>元素.

    • '//div[@id=d1]'; 选取id属性为d1的<div>元素.

    css()方法则是使用css选择器进行选择:

    • '#id': id选择器

    • '.class' class选择器

    • 'div' 标签选择器

    更多关于XPath的内容参见菜鸟教程

    更多关于Selector的讲解

    使用 item

    item的行为类似dict, 用于存储spider解析得到的数据:

    from scrapy.item import Item, Field
    
    class MyItem(Item):
    	name = Field()
        content = Field()
        url = Field()
    

    在spider.parse中将结果以item的形式返回:

    def parse(self, response):
        items = []
        for post in response.xpath('//a[@class="postTitle2"]'):
            item = MyItem()
            name = post.xpath('text()').extract()[0]
            url = post.xpath('@href').extract()[0]
            print('post:', name, url)
            item['name'] = name
            item['url'] = url
            items.append(item)
        return items
    

    更多关于item的内容参见这里

    使用Item PipeLine

    定义一个Python类,然后实现process_item(self, item, spider)方法即可作为一个PipeLine中一个过滤器的实现.

    process_item的item参数为要处理的项目, spider则是相应的spider对象.process_item返回的item对象将交给下个过滤器处理, 或者或者抛出DropItem异常丢弃这个item.

    from scrapy.exceptions import DropItem
    
    class StopWordPipeline:
    	def process_item(self, item, spider):
        	if item['name'] in stop_words:
            	raise DropItem(item['name'])
    	return item
    

    注册item只需要在settings.py中添加:

    ITEM_PIPELINES = {
        'ScrapyDemo.StopWordPipeline': 300,
        'ScrapyDemo.JsonWriterPipeline': 800,
    }
    

    值表示Pipeline的执行顺序,从低到高执行,范围0-1000.

    Scrapy Shell

    scrapy使用engine调度spider, 不便于调试.scrapy提供了shell, 在python shell环境中建立上下文以便于调试. 启动shell:

    scrapy shell <url>
    

    url为要爬取的网址.终端中建立了相关对象:

    • crawler: 当前 Crawler 对象.

    • spider : 处理URL的spider。 对当前URL没有处理的Spider时则为一个 Spider 对象。

    • request : 最近获取到的页面的 Request 对象。 您可以使用 replace() 修改该request。或者 使用 fetch 快捷方式来获取新的request。

    • response: 包含最近获取到的页面的 Response 对象。

    • sel : 根据最近获取到的response构建的 Selector 对象。

    • settings - 当前的 Scrapy settings

    可以在shell下调试选择器:

    $scrapy shell www.cnblogs.com/Finley
    >>> response
    <200 http://www.cnblogs.com/Finley>
    >>> response.xpath('//a[@class="postTitle2"]')
    ...
    

    scrapy.org

  • 相关阅读:
    Redis集群到集群迁移
    lvm磁盘创建
    前端开发环境
    golang Gorm 运用及执行原生SQL
    redis迁移两款工具
    C#知识点总结系列:3、C#中Delegate和Event以及它们的区别
    由浅入深CIL系列【目录索引】+ PostSharp AOP编程【目录索引】
    Windows 8实用窍门系列:22.Windows 8 的SemanticZoom缩放视图
    C#知识点总结系列:2、C#中IDisposable和IEnumerable、IEnumerator
    Windows 8实用窍门系列【目录索引】
  • 原文地址:https://www.cnblogs.com/Finley/p/5897918.html
Copyright © 2011-2022 走看看