使用Scrapy递归爬取网页

1. scrapy介绍与安装

  Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。(百度百科的描述)
  
  安装过程见CentOS7下安装Scrapy,基于Python2.7.5版本。

2. 项目代码与分析

(1)创建项目

scrapy startproject FinancialSpider

  可使用scrapy -h 获取使用帮助。

  生成的项目目录结构如下:  

FinancialSpider/
    FinancialSpider/
        spiders/
            __init__.py
        __init__.py
        items.py
        pipelines.py
        settings.py
    scrapy.cfg

  
主要有几个部分:

  • items.py —— 用于从网页中提取结构化数据,spider会将数据以dict形式返回
  • pipelines.py —— 用于item数据的清洗,验证,查重,保存
  • settings.py —— 用于自定义所有scrapy组件的行为
  • spiders/ —— 在该目录下的文件中定义爬虫类,用于定义爬取和解析网页的方式

(2)定义Items

import scrapy

class FinancialspiderItem(scrapy.Item):
    # define the fields for your item here like:
    html_content = scrapy.Field()

(注:本项目基于scrapy1.2.0,不同版本代码可能有差异,后文不再叙述)

由于需要抓取整个网页内容,故定义一个Field对象。

(3)定义Pipelines

import codecs

class FinancialspiderPipeline(object):
    def __init__(self):
        self.file = codecs.open('financial_file1', mode='ab', encoding='utf-8')

    def process_item(self, item, spider):
        content = item['html_content']
        #self.file.write(content.decode("unicode_escape"))
        self.file.write(content)
        return item

  初始化时以追加的模式打开数据将要保存的文件。
  
  每个Pipeline组件需要实现process_item方法,参数item为抓取的Item对象,spider为抓取item的Spider对象。方法可返回Item对象,或者raise DropItem Exception等。

  在此,将Item中的值写入保存文件。

(4)定义Settings

Settings提供了key-value映射的全局命名空间,代码中可以获取配置的值。settings.py是scrapy项目的标准配置文件,也可通过命令行选项,spider类中等方式定义。

ROBOTSTXT_OBEY = False

是否遵循robots.txt协议

COOKIES_ENABLED = False

防止了网站使用cookies识别爬虫

ITEM_PIPELINES = {
   'FinancialSpider.pipelines.FinancialspiderPipeline': 300,
}

激活自定义的Pipeline组件

DOWNLOAD_TIMEOUT = 15

减少下载超时时间,以便越过太慢的连接请求,快速进行下一网页的抓取

DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'

默认的重复请求检测过滤,可自己实现RFPDupeFilter的子类,覆写其request_fingerprint方法。

DEPTH_PRIORITY = 1
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'

scrapy默认使用LIFO队列存储请求,即以深度优先方式进行抓取。通过以上设置,以广度优先方式进行抓取。

(5)定义Spider

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.selector import Selector

from FinancialSpider.items import FinancialspiderItem

class FinancialSpider(CrawlSpider):
    """继承自CrawlSpider,实现自动爬取的爬虫。"""

    name = 'FinancialSpider'

    download_delay = 1
    # make scrapy crawl any site without allowed domains restriction
    #allowed_domains = ['eastmoney.com']
    start_urls = ['http://www.eastmoney.com']


    rules = [
        Rule(LinkExtractor(allow=(),
             restrict_xpaths=('//a[@href]')),
             callback='parse_item',
             follow=True)
    ]

    def parse_start_url(self, response):
        item = FinancialspiderItem()
        sel = Selector(response)

        content_list = sel.xpath('/html').extract()

        content = content_list[0]

        item['html_content'] = content + u'\n'

        return item


    def parse_item(self, response):
        item = FinancialspiderItem()
        sel = Selector(response)

        content_list = sel.xpath('/html').extract()

        if len(content_list) > 0:
            content = content_list[0]

            # print type(content_list)
            # print "content_len: "
            # print len(content_list)

            #print type(content)

            #item['html_content'] = [n.encode('utf-8') for n in content]
            item['html_content'] = content + u'\n'

        yield item

  在此设置了download_delay为1秒,以免访问频繁被服务器禁止访问,经验证,已满足需求。

  CrawlSpider是Spider的子类,提供了通过定义一系列rule来跟踪链接的更便利的机制。由于需要递归爬取网页,CrawlSpider更加方便。

  Rule对象定义了爬取网站的特定行为。其第一个参数Link Extractor object描述了从每个爬取网页中提取链接的方式,callback参数用于处理Link Extractor 提取的链接。

  parse_start_url方法为CrawlSpider特有的方法,用于处理start_urls指定页面的response。
  在parse_item方法中使用Selector并通过XPath实现数据的提取,在此提取的是html标签中的所有内容。

(6)使用user agent池

使用user agent池,避免服务器禁止访问。具体代码和说明参见 Scrapy研究探索(七)——如何防止被ban之策略大集合

(7)启动爬虫程序

在shell中,进入第一个FinancialSpider目录,使用以下命令启动爬虫

scrapy crawl FinancialSpider --logfile=log --loglevel=WARNING

可以看到,保存文件生成在下级目录下,内容不断增大。

(8)停止爬虫程序

可在Shell中通过按下两次ctrl-c停止爬虫。
若爬虫在后台运行,可执行两次下列代码,实现同样功能。

kill -2 $(ps -ef | grep FinancialSpider | awk '{print $2}')

3. 后续研究工作

  • 通过scrapy-redis实现分布式爬取
  • JS爬取
  • scrapy源码研究
  • ……

4. 参考文章

  1. Scrapy 1.2 documentation https://doc.scrapy.org/en/1.2/
  2. Scrapy系列教程 by young-hz http://blog.csdn.net/u012150179/article/category/2345511
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 Scrapy 爬取豆瓣 Top250,可以按照以下步骤操作: 1. 创建 Scrapy 项目 在终端中执行以下命令: ``` scrapy startproject douban_top250 ``` 这将创建一个名为 `douban_top250` 的 Scrapy 项目。 2. 创建 Spider 在项目目录下运行以下命令: ``` cd douban_top250 scrapy genspider douban_spider movie.douban.com ``` 这将在 `spiders` 目录下创建一个名为 `douban_spider.py` 的 Spider。 3. 编写 Spider 代码 打开 `douban_spider.py` 文件,并将以下代码复制到文件中: ```python import scrapy class DoubanSpider(scrapy.Spider): name = 'douban' allowed_domains = ['movie.douban.com'] start_urls = ['https://movie.douban.com/top250'] def parse(self, response): for movie in response.css('.item'): yield { 'title': movie.css('.title::text').extract_first(), 'rating': movie.css('.rating_num::text').extract_first(), 'link': movie.css('.hd a::attr(href)').extract_first(), } next_page = response.css('.next a::attr(href)').extract_first() if next_page: yield scrapy.Request(response.urljoin(next_page), callback=self.parse) ``` 这个 Spider 会访问豆瓣 Top250 页面,并提取每部电影的标题、评分和链接。它还会查找下一页的链接,并递归地调用 `parse` 方法。 4. 运行 Spider 在项目目录下运行以下命令: ``` scrapy crawl douban -o top250.csv ``` 这将运行 Spider 并将结果保存到名为 `top250.csv` 的 CSV 文件中。 以上就是使用 Scrapy 爬取豆瓣 Top250 的具体代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值