文档章节

scrapy创建项目详解---HtmlXPathSelector

Airship
 Airship
发布于 2016/03/15 09:46
字数 1476
阅读 553
收藏 0

生成项目

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就被过滤掉了


本文转载自:http://blog.csdn.net/zhang19871201/article/details/48575005

Airship
粉丝 46
博文 1065
码字总数 21602
作品 0
南京
高级程序员
私信 提问
python爬虫框架scrapy实例详解

生成项目 scrapy提供一个工具来生成项目,生成的项目中预置了一些文件,用户需要在这些文件中添加自己的代码。 打开命令行,执行:scrapy startproject tutorial,生成的项目类似下面的结构 ...

涩女郎
2016/08/28
55
0
教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。 Scrapy吸引人的地方在于...

yangjiyue0520
2017/11/18
0
0
用Scrapy抓取豆瓣小组数据(一)

最近在coursera.org(在线学习平台)上学SNA(Social Network Analysis,社交网络分析)。有兴趣的同学可以去看一眼:https://class.coursera.org/sna-002/,课程讲的很有意思,等回头我上完...

chengyao2
2013/04/21
9.4K
3
scrapy爬虫架构介绍和初试

scrapy爬虫架构介绍和初试 一、scrapy简介 Scrapy 是一套基于Twisted的异步处理框架,是纯python实现的爬虫框架,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容或者...

zhujun2017
2018/07/23
10
0
使用Python的Scrapy框架编写web爬虫的简单示例

在这个教材中,我们假定你已经安装了Scrapy。假如你没有安装,你可以参考这个安装指南。 我们将会用开放目录项目(dmoz)作为我们例子去抓取。 这个教材将会带你走过下面这几个方面: 创造一个新的...

Airship
2016/04/09
156
1

没有更多内容

加载失败,请刷新页面

加载更多

JS--function

一、声明提前(hoist) 在js程序开始执行前,引擎会查找所有var声明的变量和function声明的函数,集中到当前作用域顶部集中创建,赋值留在原地 二、三种创建函数的方式 1、声明方式创建函数-...

wytao1995
今天
4
0
微服务之间调用控制器注解类型的差异

今天在一个业务服务通过Feign调用文件服务上传文件时遇到了几个问题: 1. 提示http请求头过大的问题; 此时需要修改bootstrap.yml,加入 server: max-http-header-size: 10000000 用以放大...

不再熬夜
今天
5
0
用 4G 工作是什么体验

七月开始,因为工作原因,在公司附近租了个住处,方便工作。离公司近了,感觉就是不一样,之前每天 5:30 就要起床赶地铁,现在可以睡到自然醒,一看才 7 点,悠闲的起床洗漱,踱步到公司,都...

zzxworld
今天
6
0
sonar报错volatile

问题发生 原先代码如下: //认证授权码private static volatile String AUTHORIZATION_CODE = "init"; git push 之后,sonar认为这是个bug检测报告截图如下: 分析排查 解释说明: Markin...

开源小菜鸟2333
今天
5
0
《Java实践指南》--读后

闲读《Java实践指南》... 1.lvy 某些项目中能够看到ivy.xml。早期使用ant的项目中,常常用ivy.xml来下载项目依赖。 2.ant 作为java程序员,应该都知道ant,虽然可能用过的人不多。为什么ant...

RippleChan
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部