zoukankan      html  css  js  c++  java
  • scrapy爬虫笔记(三)写入源文件的爬取

    开始爬取网页:(2)写入源文件的爬取

      为了使代码易于修改,更清晰高效的爬取网页,我们将代码写入源文件进行爬取。

      主要分为以下几个步骤:

        一.使用scrapy创建爬虫框架:

        二.修改并编写源代码,确定我们要爬取的网页及内容

        三.开始爬取并存入文件(数据库)

    注:为了避免冗长的叙述,更直观地理解,这里先讲具体的操作方法,如果想要深入理解其原理,具体解释在最后。

    *操作方法:

      1.创建爬虫框架

      打开命令行,使用cd命令,进入你想要创建文件的位置

      scrapy startproject 文件夹名称(假设为demo

        scrapy startproject demo

      强大的scrapy会在当前路径下自动生成爬虫框架如下:demo/

          scrapy.cfg						#项目配置文件
          demo/
              __init__.py
              items.py	          #设定数据存入的对象
              pipelines.py	        #与数据库交互
              settings.py					#爬虫配置文件
              spiders/
                  	__init__.py
      2.编辑源代码,确定爬取方案
      scrapy不仅仅帮助我们生成好了框架,还提供了很多内置的方法供我们使用,我们只需要利用这些方法并结合BeautifulSoup库
    进行网页信息的筛选。

      开始写代码吧!
      首先打开items.py文件,修改如下:
     1 # -*- coding: utf-8 -*-
     2 
     3 # Define here the models for your scraped items
     4 #
     5 # See documentation in:
     6 # http://doc.scrapy.org/en/latest/topics/items.html
     7 
     8 import scrapy
     9 
    10 
    11 class DemoItem(scrapy.Item):
    12     # define the fields for your item here like:
    13     name = scrapy.Field()
    14     #pass

      然后在spider目录下新建spider.py,将下述代码复制到其中
     1 # -*- coding: utf-8 -*-
     2 import scrapy
     3 from bs4 import BeautifulSoup
     4 from demo.items import DemoItem
     5 
     6 class demo(scrapy.Spider):
     7     name = "demo"
     8     start_urls = ['http://www.cnblogs.com/KoalaDream/']
     9 
    10     def parse(self, response):
    11         soup = BeautifulSoup(response.body)
    12         tmp=soup.find_all('div',attrs={'class':'postTitle'})
    13         for i in range(0,len(tmp)):
    14             item=DemoItem()
    15             item['name']=tmp[i].text.encode('utf-8')
    16             yield item
    
    

      这段代码的作用是爬取我的博客主页的文章标题,具体语句的作用在后面有介绍。

      3.开始爬取并存入文件

        代码编写好了,我们要开始爬取网页了,是不是很容易?

        在命令行中,使用cd命令进入scrapy.cfg所在的目录

          scrapy crawl demo -o output.json

        开始爬取,并将内容输出到含有scrapy.cfg文件的目录下output.json文件中 

      完成!

     

      打开output.json文件,什么?怎么全是乱码?

      这是因为我们爬取下的中文字符,以unicode的编码格式存储在文件中。

      想要看到中文字符,可以将输出的内容复制,打开python,输入print u"---"将复制的unicode码粘贴,便可输出对应的中文字符。

    *代码详解 

      首先,设置编码格式为utf-8,能够显示中文注释。

      在spider中,scrapy框架规定其中有三个必需的定义的成员。

        name: 名字,spider的标识,我们爬取时在命令行中输入的 scrapy crawl ____ 即为此处定义的name

        start_urls:一个url列表,spider从这些网页开始抓取

        parse():一个方法,当start_urls里面的网页抓取下来之后scrapy会自动调用这个方法解析网页内容。

      总的来说就是name告诉scrapy框架,我要运行哪个框架。然后scrapy会运行该框架,自动链接到start_url的web页面,生成response对象,将爬取下源代码存入response对象里面。

     

      下面我们来看具体的parse()方法是如何工作的。

      首先引入BeautifulSoup库,它可以大大简化我们的爬取过程。

      然后我们打开要爬取的网页即 http://www.cnblogs.com/KoalaDream/

      查看源代码。(chrome浏览器中,鼠标右键点击某一个文章标题,点击审查元素)

      可以看到,每一个标题都是在一个<div>标签里面,class属性均为postTitle

      于是,我们使用BeautifulSoup中提供的方法筛选出标题

        tmp=soup.find_all('div',attrs={'class':'postTitle'})

      将标题以列表的形式存入tmp中。

      还记得我们刚刚修改过的items.py文件吗?

      下面我们要遍历tmp中的每一项,并将其存入刚刚定义过的item中。

      通过 item=DemoItem(),创建了一个DemoItem类的对象,下面的操作

        item['name']=tmp[i].text.encode('utf-8')

      左侧的运算符有些让人费解。因为想要操作类中的成员,一般使用item.name,这个操作符是怎么回事呢?

      仔细观察items.py文件中,DemoItem类继承了scrapy.Item类。经试验证明,如果把继承去除,此运算符不再存在。

      说明在scrapy.Item类中,对运算符[]进行了重载。个人感觉意义上和.操作符没什么区别,我们直接使用此语法即可。

      最后就是 yield item了

      yield语法查了很久,已经被生成器,迭代器搞得有些晕。

      如果想了解具体的yield语法,请看下面的链接  

      http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained

      对于这里的yield语句的作用,我说说我的理解,哪里不准确希望大家多多指教。

      首先简单介绍下yield语句:

      yield用于函数,就像return,给函数一个返回值。不同的是,return标志着函数结束,而yield是让函数暂停,直到这个函数再次被调用,会从暂停的地方继续执行,而不是从头开始。

      在spider.py的代码中,每循环一次,yield语句将列表中当前的值返回给parse。可是我们并没有主动调用和返回。那么输出的内容是哪里来的?

      因为parse是在scrapy框架中,自动被调用的方法,我们可以推测出:

      当告诉scrapy输出到output.json文件中时,对于每一次yield的返回值,会被自动print到output.json文件中。然后scrapy会再次调用parse方法,从刚刚间断的位置,即for循环的下一个列表项开始。如此循环,直到函数结束。这样一来,tmp中的内容就被存放到item['name']中,然后被输出到output.json中。

      每一次yield返回的一个值就是所谓的生成器。

      而每一次从暂停状态,再被调用时,自动从暂停前的下一个对象开始,就是所谓的迭代器。

      附:官方文档

        Scrapy  http://doc.scrapy.org/en/latest/

  • 相关阅读:
    linux音频alsa-uda134x驱动文档阅读之一转自http://blog.csdn.net/wantianpei/article/details/7817293
    linux音频alsa-uda134x驱动分析之二(时钟)
    linux下定时器介绍1
    linux下定时器介绍2--timer_create等函数集的使用示例
    linux 获取时间后--自定义时间格式
    linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction
    高通QMI协议
    linux sigaction 函数 用法释义
    NB-iot 和 emtc两种技术区别
    如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级
  • 原文地址:https://www.cnblogs.com/KoalaDream/p/4470482.html
Copyright © 2011-2022 走看看