文档章节

python爬虫框架scrapy实例详解

涩女郎
 涩女郎
发布于 2016/08/28 10:43
字数 1478
阅读 55
收藏 2

生成项目

scrapy提供一个工具来生成项目,生成的项目中预置了一些文件,用户需要在这些文件中添加自己的代码。

打开命令行,执行:scrapy startproject tutorial,生成的项目类似下面的结构

tutorial/

   scrapy.cfg

   tutorial/

       __init__.py

       items.py

       pipelines.py

       settings.py

       spiders/

           __init__.py

           ...

scrapy.cfg是项目的配置文件

用户自己写的spider要放在spiders目录下面,一个spider类似

1

2

3

4

5

6

7

8

9

10

11

from scrapy.spider import BaseSpider

class DmozSpider(BaseSpider):

    name = "dmoz"

    allowed_domains = ["dmoz.org"]

    start_urls = [

        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",

        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"

    ]

    def parse(self, response):

        filename = response.url.split("/")[-2]

        open(filename, 'wb').write(response.body)

name属性很重要,不同spider不能使用相同的name

start_urls是spider抓取网页的起始点,可以包括多个url

parse方法是spider抓到一个网页以后默认调用的callback,避免使用这个名字来定义自己的方法。

当spider拿到url的内容以后,会调用parse方法,并且传递一个response参数给它,response包含了抓到的网页的内容,在parse方法里,你可以从抓到的网页里面解析数据。上面的代码只是简单地把网页内容保存到文件。

 

开始抓取

你可以打开命令行,进入生成的项目根目录tutorial/,执行 scrapy crawl dmoz, dmoz是spider的name。

 

解析网页内容

scrapy提供了方便的办法从网页中解析数据,这需要使用到HtmlXPathSelector

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

from scrapy.spider import BaseSpider

from scrapy.selector import HtmlXPathSelector

class DmozSpider(BaseSpider):

    name = "dmoz"

    allowed_domains = ["dmoz.org"]

    start_urls = [

        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",

        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"

    ]

    def parse(self, response):

        hxs = HtmlXPathSelector(response)

        sites = hxs.select('//ul/li')

        for site in sites:

            title = site.select('a/text()').extract()

            link = site.select('a/@href').extract()

            desc = site.select('text()').extract()

            print title, link, desc

HtmlXPathSelector使用了Xpath来解析数据

//ul/li表示选择所有的ul标签下的li标签

a/@href表示选择所有a标签的href属性

a/text()表示选择a标签文本

a[@href="abc"]表示选择所有href属性是abc的a标签

我们可以把解析出来的数据保存在一个scrapy可以使用的对象中,然后scrapy可以帮助我们把这些对象保存起来,而不用我们自己把这些数据存到文件中。我们需要在items.py中添加一些类,这些类用来描述我们要保存的数据

from scrapy.item import Item, Field

class DmozItem(Item):

   title = Field()

   link = Field()

   desc = Field()

然后在spider的parse方法中,我们把解析出来的数据保存在DomzItem对象中。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

from scrapy.spider import BaseSpider

from scrapy.selector import HtmlXPathSelector

from tutorial.items import DmozItem

class DmozSpider(BaseSpider):

   name = "dmoz"

   allowed_domains = ["dmoz.org"]

   start_urls = [

       "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",

       "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"

   ]

   def parse(self, response):

       hxs = HtmlXPathSelector(response)

       sites = hxs.select('//ul/li')

       items = []

       for site in sites:

           item = DmozItem()

           item['title'= site.select('a/text()').extract()

           item['link'= site.select('a/@href').extract()

           item['desc'= site.select('text()').extract()

           items.append(item)

       return items

在命令行执行scrapy的时候,我们可以加两个参数,让scrapy把parse方法返回的items输出到json文件中

scrapy crawl dmoz -o items.json -t json

items.json会被放在项目的根目录

 

让scrapy自动抓取网页上的所有链接

上面的示例中scrapy只抓取了start_urls里面的两个url的内容,但是通常我们想实现的是scrapy自动发现一个网页上的所有链接,然后再去抓取这些链接的内容。为了实现这一点我们可以在parse方法里面提取我们需要的链接,然后构造一些Request对象,并且把他们返回,scrapy会自动的去抓取这些链接。代码类似:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

class MySpider(BaseSpider):

    name = 'myspider'

    start_urls = (

        'http://example.com/page1',

        'http://example.com/page2',

        )

    def parse(self, response):

        # collect `item_urls`

        for item_url in item_urls:

            yield Request(url=item_url, callback=self.parse_item)

    def parse_item(self, response):

        item = MyItem()

        # populate `item` fields

        yield Request(url=item_details_url, meta={'item': item},

            callback=self.parse_details)

    def parse_details(self, response):

        item = response.meta['item']

        # populate more `item` fields

        return item

 

parse是默认的callback, 它返回了一个Request列表,scrapy自动的根据这个列表抓取网页,每当抓到一个网页,就会调用parse_item,parse_item也会返回一个列表,scrapy又会根据这个列表去抓网页,并且抓到后调用parse_details

为了让这样的工作更容易,scrapy提供了另一个spider基类,利用它我们可以方便的实现自动抓取链接. 我们要用到CrawlSpider

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor

class MininovaSpider(CrawlSpider):

    name = 'mininova.org'

    allowed_domains = ['mininova.org']

    start_urls = ['http://www.mininova.org/today']

    rules = [Rule(SgmlLinkExtractor(allow=['/tor/\d+'])),

             Rule(SgmlLinkExtractor(allow=['/abc/\d+']), 'parse_torrent')]

    def parse_torrent(self, response):

        = HtmlXPathSelector(response)

        torrent = TorrentItem()

        torrent['url'= response.url

        torrent['name'= x.select("//h1/text()").extract()

        torrent['description'= x.select("//div[@id='description']").extract()

        torrent['size'= x.select("//div[@id='info-left']/p[2]/text()[2]").extract()

        return torrent

相比BaseSpider,新的类多了一个rules属性,这个属性是一个列表,它可以包含多个Rule,每个Rule描述了哪些链接需要抓取,哪些不需要。这是Rule类的文档http://doc.scrapy.org/en/latest/topics/spiders.html#scrapy.contrib.spiders.Rule

这些rule可以有callback,也可以没有,当没有callback的时候,scrapy简单的follow所有这些链接.

pipelines.py的使用

在pipelines.py中我们可以添加一些类来过滤掉我们不想要的item,把item保存到数据库。

1

2

3

4

5

6

7

8

9

10

11

12

from scrapy.exceptions import DropItem

class FilterWordsPipeline(object):

    """A pipeline for filtering out items which contain certain words in their

    description"""

    # put all words in lowercase

    words_to_filter = ['politics''religion']

    def process_item(self, item, spider):

        for word in self.words_to_filter:

            if word in unicode(item['description']).lower():

                raise DropItem("Contains forbidden word: %s" % word)

        else:

            return item

如果item不符合要求,那么就抛一个异常,这个item不会被输出到json文件中。

要使用pipelines,我们还需要修改settings.py

添加一行

ITEM_PIPELINES = ['dirbot.pipelines.FilterWordsPipeline']

现在执行scrapy crawl dmoz -o items.json -t json,不符合要求的item就被过滤掉了

© 著作权归作者所有

涩女郎
粉丝 37
博文 104
码字总数 160210
作品 0
浦东
高级程序员
私信 提问
Python3爬虫视频学习教程

大家好哈,现在呢静觅博客已经两年多啦,可能大家过来更多看到的是爬虫方面的博文,首先非常感谢大家的支持,希望我的博文对大家有帮助! 最近,主要的任务就是开发性感美女图片大全,使用p...

yangjiyue0520
2017/11/18
0
0
Python | 初识爬虫框架Scrapy

一、前言 今天给大家分享的是,Python里的爬虫框架Scrapy学习,包含python虚拟环境的搭建、虚拟环境的使用、Scrapy安装方法详解、Scrapy基本使用、Scrapy项目目录及内容基本介绍,let's go!...

技术小能手
2018/09/07
0
0
一个月入门Python爬虫,快速获取大规模数据

数据是创造和决策的原材料,高质量的数据都价值不菲。而利用爬虫,我们可以获取大量的价值数据,经分析可以发挥巨大的价值,比如: 豆瓣、知乎:爬取优质答案,筛选出各话题下热门内容,探索...

Python开发者
2018/04/25
0
0
[雪峰磁针石博客]2018最佳人工智能数据采集(爬虫)工具书下载

Python网络数据采集 Python网络数据采集 - 2016.pdf 本书采用简洁强大的Python语言,介绍了网络数据采集,并为采集新式网络中的各种数据类型提供了全面的指导。第 1部分重点介绍网络数据采集...

python测试开发人工智能安全
2018/11/07
241
0
高级爬虫(一):Scrapy爬虫框架的安装

Hi 小伙伴们差不多有半个月没有更新干货了,一直有点忙,而且这中间还有曲折过程,也就没有更新文章. 但今天无论如何也要更新一篇文章,接下来是爬虫高级篇重点讲解的地方! 最近会连载Scrap...

Python绿色通道
2018/04/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
4分钟前
0
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
16分钟前
1
0
jenkins 插件下载加速最终方案

推荐做法 1、告诉jenkins 我哪些插件需要更新 jenkins插件清华大学镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 1.进入jenkins系统管理 2.进入插件管...

vasks
22分钟前
2
0
composer爆错:zlib_decode():data error

解决办法:先用 composer diagnose 命令检测 然后 composer self-update 更新composer版本 最后执行 composer update 或者 composer install composer 切换阿里云镜像 用起来还快 composer c...

koothon
29分钟前
2
0
shangcheng-my

1.数据库主键、外键类型为bigint,那么在后台应该用什么类型的变量定义? 后台用string接收,因为前段传过来的一般都是json字符串,后台直接接收,mysql是可以吧数字类型的字符串转换为对应的...

榴莲黑芝麻糊
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部