Python实现爬虫:Scrapy爬取csdn博客

在上篇教程中,已经尝试安装好Scrapy,并且解决好了环境问题,这篇文章将创建一个Scrapy项目

包含的步骤主要为:

1、创建一个Scrapy项目

2、定义提取的字段信息Item

3、编写爬取网站的 spider 并提取 Item

4、编写 Item Pipeline 来存储提取到的Item(即数据)

 

创建爬虫项目

开始爬取之前,必须创建一个新的Scrapy项目。 进入希望存储代码的目录中,运行下列命令:

scrapy startproject Alice

该命令将创建一个project项目,名称为Alice,并包含下列内容的 Alice 目录,:

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

这些文件分别是:

  • scrapy.cfg: 项目的配置文件
  • Alice: 该项目的python模块。之后您将在此加入代码。
  • Alice/items.py: 项目中的item文件.
  • Alice/pipelines.py: 项目中的pipelines文件.
  • Alice/settings.py: 项目的设置文件.
  • Alice/spiders/: 放置spider代码的目录.

 

定义保存数据的容器Item

Item 是保存爬取到的数据的容器,并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。

通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个Item。 

首先根据需要从csdn.blog获取到的数据对item进行建模。 我们需要从csdn中获取名字,url,以及网站的描述。 对此,在item中定义相应的字段。编辑 Alice 目录中的 items.py 文件:

import scrapy


class AliceItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    # 标题
    title = scrapy.Field()
    # 详情连接
    link = scrapy.Field()
    # 阅读
    read = scrapy.Field()
    # 点赞
    love = scrapy.Field()
    # 分类
    blogtype = scrapy.Field()
    
    pass

 

编写爬虫(Spider)

Spider是用户编写用于从单个网站(或者一些网站)爬取数据的类。包含如下内容:

  • 一个用于下载的初始URL
  • 如何跟进网页中的链接
  • 如何分析页面中的内容
  • 提取生成 item 的方法。

为了创建一个Spider,必须继承 scrapy.Spider 类, 且定义以下三个属性:

  • name: 用于区别Spider。 该名字必须是唯一的,为不同的Spider设定相同的名字是不允许的。
  • start_urls: 包含Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
  • parse() :是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

创建一个spider文件,进入Alice目录,使用命令创建一个基础爬虫类:

#  alicepostion为爬虫名,为爬虫作用范围
scrapy genspider alicepostion "blog.csdn.net/alice_tl"

以下为Spider代码,保存在 Alice/spiders 目录下的 aliceposition.py 文件中:

# -*- coding: utf-8 -*-
import scrapy
from Alice.items import AliceItem

class alicepostionSpider(scrapy.Spider):
    #功能:爬取alice
    name = 'alicepostion'
    #爬虫名字
    allowed_domains = ['blog.csdn.net/alice_tl']
    #爬虫作用范围
    start_urls = ['https://blog.csdn.net/alice_tl/']
    #爬虫起始url

    offset = 0

    def parse(self, response):
        for each in response.xpath("//tr[@class='even'] | //tr[@class='odd']"):
            # 初始化模型对象
            item = AliceItem()
           
            # 标题
            item['title'] = each.xpath("./td[1]/a/@href").extract()[0]
            # 连接
            item['link'] = each.xpath("./td[2]/text()").extract()[0]
            # 阅读
            item['read'] =  each.xpath("./td[3]/text()").extract()[0]
            # 点赞
            item['love'] = each.xpath("./td[4]/text()").extract()[0]
            # 分类
            item['blogtype'] = each.xpath("./td[5]/text()").extract()[0]

            yield item

        if self.offset < 1680:
            self.offset += 10

        # 每次处理完一页的数据之后,重新发送下一页页面请求
        # self.offset自增10,同时拼接为新的url,并调用回调函数self.parse处理Response
        yield scrapy.Request(self.url + str(self.offset), callback = self.parse)

    def parse(self, response):

        filename = '/Users/alice/Documents/Develop/PythonCode/alicescrapy.xlsx'
        #文件路径和文件名
        with open(filename,'wb' ) as f:
        #打开一个文件
            f.write(response.body)
            #将返回内容写进去
        print(f.read())
        pass

 

启动爬虫爬取

进入项目的根目录,执行下列命令启动spider:

scrapy crawl alicepostion

查看包含 [alicepostion] 的输出,可以看到输出的log中包含定义在 start_urls 的初始URL,并且与spider中是一一对应的。在log中可以看到其没有指向其他页面( (referer:None) )。

2019-04-20 11:13:58 [scrapy.core.engine] INFO: Spider opened
2019-04-20 11:13:58 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-04-20 11:13:58 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: None)
2019-04-20 11:13:58 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: None)
2019-04-20 11:13:58 [scrapy.core.scraper] ERROR: Spider error processing  (referer: None)
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/twisted/internet/defer.py", line 654, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/Users/alice/Alice/Alice/spiders/alicepostion.py", line 47, in parse
    with open(filename, '/Users/alice/Documents/Develop/PythonCode/alicescrapy.csv') as f:
ValueError: invalid mode: '/Users/alice/Documents/Develop/PythonCode/alicescrapy.csv'
2019-04-20 11:13:58 [scrapy.core.engine] INFO: Closing spider (finished)
2019-04-20 11:13:58 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 554,
 'downloader/request_count': 2,
 'downloader/request_method_count/GET': 2,
 'downloader/response_bytes': 10981,
 'downloader/response_count': 2,
 'downloader/response_status_count/200': 2,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2019, 4, 20, 3, 13, 58, 885429),
 'log_count/DEBUG': 2,
 'log_count/ERROR': 1,
 'log_count/INFO': 7,
 'log_count/WARNING': 1,
 'memusage/max': 65769472,
 'memusage/startup': 65769472,
 'response_received_count': 2,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/200': 1,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'spider_exceptions/ValueError': 1,
 'start_time': datetime.datetime(2019, 4, 20, 3, 13, 58, 384500)}
2019-04-20 11:13:58 [scrapy.core.engine] INFO: Spider closed (finished)

爬虫运行后会生成一个alicescapy.xlsx的文件,打开内容如下:

Python实现爬虫:Scrapy爬取csdn博客_第1张图片

你可能感兴趣的:(Python)