美文网首页
Python Scrapy———豆瓣Top250

Python Scrapy———豆瓣Top250

作者: AquilaP | 来源:发表于2015-10-04 22:30 被阅读1281次

    1.Scrapy简介

            最开始看Scrapy的教程是中文版 ,这个版本是0.24,后来python模块warning的时候,去查看英文版,结果人家已经更新到1.0+了,很多import的模块已经有了一些改变,这里要注意。参与翻译scrapy的作者在他的github上说:

            Scrapy的文档写得很详细,与之带来的就是文档量很大。仅仅靠我需要很多的时间。希望您能加入这个计划,让翻译更快速。

            确实工作量非常大。这里也相参与翻译的工作人员致敬~       

            个人对Scrapy的印象是这样的:它专门为了scrapy而设计,里面有一个“半自动”化的结构,包括图1.1:

    图1.1 scrapy 架构图            

            (1)Scrapy Engine:相当于“经销商”,它负责什么时候向Spider买url,决定买多少,并卖给Scheduler;

             (2)Spider:就是辛辛苦苦作劳动的机器人,它向Engine提供url以及相应的Rule,这是整个获取数据的关键,在你建立的scrapy项目下有一个文件夹叫:spider,里面放了spider的主程序,具体后面介绍。

            (3)Scheduler:故名思意,就是调度,根据Engine给它的url产生各种request信息;

            (4)Downloader:根据接受到的request信息进行下载,产生response对象,返还给spider处理;

            (5)Item/Pipeline:spider在接受到response对象后,自动或者根据callback进行parse,然后把处理好的数据装进item或者输出到文件。

            Scrapy内置了很多方法,我们要做的就是利用这种方法,告诉scrapy我要怎么做,具体谁发送request,谁接收response,item怎么传递的,那么就是由scrapy自己的逻辑实现,这个我们不用操心。但是还要明白spider里面各个method被执行的先后顺序,这样会使自己的逻辑非常清楚。不然scrapy就是一个黑箱,用的时候哪里有问题也不知道。



    2.Scrapy使用方法

            这里对于使用scrapy非常重要,弄清楚了各个method的功能和顺序才能有的放矢。

            如果这里对于python不是很熟悉,可以找找python教材中“类”的那一章看看。

    PS:本文基于linux平台,使用vim编程

    (1)创建scrapy的project

            在命令行输入:

    cd ~/Produre #进入Podure目录下,在这个目录下建立projecy

    scrapy startproject XXX #建立名为 XXX的project 

    此时在Proodure目录下会自动建立一个类似下面这样的文件结构:

    图2:scrapy项目文件结构

            item.py是你要定义item的地方,item你就理解为spider后要把数据存入的地方,item就可以理解为一个字典。

            pipeline可以理解为管道,当你获得的数据很多,不断产生时,用item存储的数据会被覆盖,而此时通过编写pipeline的class和method可以实现将数据源源不断的写入指定的文件类型中,后面介绍。

          settings.py是存放spider的一些配置信息的,比如下载时间间隔,pipeline中类的名字,以及按照什么样的顺序进行下载。后面介绍。

            spider文件夹下存放编写爬虫的主要文件。

    (2)定义Item

    打开item.py,然后按照你想要存储的数据,进行编写:

    图3:编写item

            每一个定义的变量都可以在spider中作为item字典的键,不过这首先要被赋予scrapy.Field()

    (3)Spider中的类和方法

    定义好item后,就可以编写spider程序了,但在这之前介绍以下各种方法和类:

    name:必须且唯一的spider名字,类型为string,运行该spider时输入它

    allow_domains:允许方法的域名,可以是string 或者list,可选项,非必须。

    start_urls: 指定要首先访问的url

    方法:

    start_requests(): 默认从start_urls里面获取url,并且为每一个url产生一个request,默认的    callback为parse。调度就是从这里开始执行的。这里可以改写,以便从指定的url开始访问,一般用于模拟登陆时,获取动态code的时候。获取动态code那么你可以这样:

    from scrapy.http import Request,FromRequest

    start_requests():

        return [ Request( url, mata={'cookiejar':1}callback=login ) ] #加入meta想要获取cookie

            这里的url就是你登陆的login URL,访问这个url时,server会返回你一个response,这个response里面就有下一步登陆的时候要发送的code。那么这里的callback到login这个方法的功能就是要从返回的response里面通过正则表达式或者结合xpath等得到这个code。

            start_requests中将Downloader下载的response返回给callback,也就是我定义的login方法,那么在login方法中,除了要解析并获得动态code外,还可以进行模拟登陆,在login中可以加入:

    def login(self,response):

          code=response.xpath('//h1/text()').extract() #就是为了获得code,也可以结合re来提取

          headers={} #模拟浏览器登陆的header

          postdata={} #server要你post的数据,包括上面获得的code

          return [FormRequest.from_response(    url,  headers=headers, formdata=postdata,  meta={'cookiejar':response.meta['cookiejar'],  callback=loged  , dont_filter=x   }  )   ]

          #注意这里postdata并没有用urlencode,且cookie用的是返回的response中的cookie,也就是上面start_requests那里记录的cookie。另外此时的url则是你真正post数据的url,一般可以通过firebug获得。其实,这里也可以这个时候才获得cookie,这样可以获得登陆以后的cookie。这个方法被调用以后,就成功登陆了,那么此时可以在loged方法中通过下面make_requests_from_url这个方法来访问登陆以后的其他页面。

          #这里如果需要输入验证码,可以采用下载图片并手动输入的方式进行,在另外一片记录里可以看到。

       

            如果该方法被重写了,那么start_urls里面的url将不会被首先访问,后面想要访问的时候则要特别的“强调“。会在后面说明。

          还要注意的是,start_requests只被自动调用一次。

    make_requests_from_url(url):

            这个方法就是当你指定了url的时候,则通过这个方法,可以自动返回给parse。scrapy中能够自动调用parse的方法,就我目前的学习来看,只有这两个(start_requests和make_requests_from_url)。这个之所以重要,是因为要结合后面说的CrawlSpider中的rule。

            可以通过make_requests_from_url()来实现访问start_urls里面的url:

    def loged(self, response):

        for url in start_urls:

            yield make_requests_from_url(url)

    parse():

           scrapy中默认将response传递到的地方就是parse(),这里顾名思义是用来提取网页内容的地方,在Spider类中可以在这里实现网页内容提取,但是在CralwSpider中,parse()实现用rule中获得的link进行进一步处理,所以在CrawlSpider中不建议重写parse方法。

    rule():

            rule提供了如何指导Downloader获取链接的的功能,其具体实现是:

    from scrapy.linkextractors import LinkExtractor as LKE

    图:rule举例

    LinkExtractor的教程见:linkextractor 

    linkextractor的参数这里主要用到:

    (1)allow=(这里用正则表达式写明要获取的链接)

    (2)restrict_xpaths=(这里要用xpath格式写明特别要从哪个节点获取链接)

    在Rule里面,特别要注意callback后面要加的是string,而不是向类中引用其他方法的self.parse_1。follow意位“跟踪”,那其实这里是有一个思考的。

            rule是通过调用parse()方法来按照其里面提供的各种Rule来进行链接获取及response的返回,其逻辑是这样的:

    (1)必须调用parse

    (2)然后按照Rule规则,在parse中的response中寻找符合Rule指定规则的链接

    (3)如果找到了相应的链接,那么请求这个链接,并把这个链接的response发送给callback,进行分析

    (4)然后考虑是否跟进,如果跟进,那么以这个链接为基点再按照Rule中规则进行寻找

            这里就存在两个问题,第一个发送到rule中的response,其实是没有被传给callback的;另外就是如果follow=False,那么其实......(未完待续)

    相关文章

      网友评论

          本文标题:Python Scrapy———豆瓣Top250

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