从零开始学爬虫(二)

81 阅读4分钟

在上一篇文章中,我们简单学习了如何用requests库进行简单的爬虫,对于数据量较小的数据爬取,可以使用这种方式进行爬虫。

但如果要爬取的数据量较大,对性能有一定要求的话,就需要使用一些爬虫框架了。(其实requests+各种解析器已经较为好用了,但对于比较通用性的爬虫,框架可以提高效率,不用写那么多代码)

本篇文章来学习一下较常用的爬虫框架scrapy的使用

scrapy框架介绍

比较流行的爬虫的框架有scrapypyspiderscrapy的使用可能更广一些。

scrapy是一个开源的高级爬虫框架,使用python编写,用于爬取网页,提取结构性数据,并可将抓取得结构性数据较好的应用于数据分析和数据挖掘。

scrapy有以下的一些特点:

  • scrapy基于事件的机制,利用twisted的设计实现了非阻塞的异步操作。这相比于传统的阻塞式请求,极大的提高了CPU的使用率,以及爬取效率。
  • 配置简单,可以简单的通过设置一行代码实现复杂功能。
  • 可拓展,插件丰富,比如分布式scrapy + redis、爬虫可视化等插件。
  • 解析方便易用,scrapy封装了xpath等解析器,提供了更方便更高级的selector构造器,可有效的处理破损的HTML代码和编码。

使用方式

1、安装 Scrapy

pip install scrapy

2、创建一个scrapy项目(提取进到你要放这个项目的路径)

scrapy startproject spider_test

3、自动生成的项目的代码结构如下图

image.png

  • scrapy.cfg: 项目的配置文件。
  • items.py: 项目的目标文件。
  • pipelines.py: 项目的管道文件。
  • settings.py: 项目的设置文件。
  • spiders/: 存储爬虫代码目录。

4、爬取数据 假如我们要爬取豆瓣电影的top250的电影名,电影类型,以及海报url

目标网站:movie.douban.com/top250

4.1 创建一个Item Item 是保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。

类似在ORM中做的一样,您可以通过创建一个 scrapy.Item类, 并且定义类型为 scrapy.Field的类属性来定义一个Item。

首先我们创建一个filmItem(在items.py 中增加一下代码)

class FilmItem(scrapy.Item):
    name = scrapy.Field()
    type = scrapy.Field()
    img = scrapy.Field()

image.png

4.2 在命令行执行

scrapy genspider FilmItem "movie.douban.com/top250"

自动生成爬虫模版代码(也可以自己写,主要就是创建一个spider类)

image.png

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

4.3 修改starts_url为要爬取的url

image.png

4.4 利用xpath规则提取响应数据

def parse(self, response):
    for li in response.xpath("//ol[@class='grid_view']/li"):
        item = FilmItem()
        item['name'] = li.xpath(".//div[@class='hd']/a/span[@class='title']/text()").extract_first()
        item['type'] = li.xpath(".//div[@class='hd']/a/span[@class='other']/text()").extract_first()
        item['img'] = li.xpath(".//div[@class='pic']/a/img/@src").extract_first()
        yield item

xpath 规则需要另外学习一下

4.5 开始爬虫 整个FilmItem的代码如下,import的路径需要根据你的使用修改一下

import scrapy
import sys

sys.path.append("/Users/***/PycharmProjects/web Spider/step_2_framework/spider_test/spider_test/")
from items import FilmItem

from scrapy import Request


class FilmitemSpider(scrapy.Spider):
    name = 'FilmItem'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com/top250/']

    def start_requests(self):
        for i in range(10):
            url = f'https://movie.douban.com/top250?start={25 * i}&filter='
            yield Request(url=url, callback=self.parse)

    def parse(self, response):
        for li in response.xpath("//ol[@class='grid_view']/li"):
            item = FilmItem()
            item['name'] = li.xpath(".//div[@class='hd']/a/span[@class='title']/text()").extract_first()
            item['type'] = li.xpath(".//div[@class='hd']/a/span[@class='other']/text()").extract_first()
            item['img'] = li.xpath(".//div[@class='pic']/a/img/@src").extract_first()
            yield item

ps.在获取页面之前scrapy先访问了robots.txt文件,这是一个良好的爬虫习惯,此时scrapy的所有页面获取都将会遵从robots.txt里面的规则,如果你不想遵从这一规则可以在settings里配置ROBOTSTXT_OBEY = False

4.6 配置 setting.py文件中增加两天配置

ROBOTSTXT_OBEY = False

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'

4.7 执行爬虫

 scrapy crawl FilmItem  -o items.csv

将爬取到的数据保存到csv文件中

image.png

感觉使用起来也并没有使用request+解析器方便多少

Reference

juejin.cn/post/684490…