使用 Scrapy 框架来爬取数据

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 创建一个 Scrapy 项目,项目文件可以直接用 scrapy 命令生成,命令如下所示:scrapy startproject doubanmovie250 这个命令可以在任意文件夹运行。如果提示权限问题,可以加 sudo 运行该命令。

1.创建项目

创建一个 Scrapy 项目,项目文件可以直接用 scrapy 命令生成,命令如下所示:scrapy startproject doubanmovie250 这个命令可以在任意文件夹运行。如果提示权限问题,可以加 sudo 运行该命令。这个命令将会创建一个名为 doubanmovie250 的文件夹,文件夹结构如下所示:

网络异常,图片无法展示
|

2.创建Spider

Spider 是自己定义的类,Scrapy 用它来从网页里抓取内容,并解析抓取的结果。不过这个类必须继承 Scrapy 提供的 Spider 类 scrapy.Spider,还要定义 Spider 的名称和起始请求,以及怎样处理爬取后的结果的方法。也可以使用命令行创建一个Spider。比如要生成 doubanmovie250 这个 Spider,可以执行如下命令:scrapy genspider doubanmovie250 douban.com,进入刚才创建的 doubanmovie250 文件夹,然后执行 genspider 命令。第一个参数是 Spider 的名称,第二个参数是网站域名。执行完毕后,spiders 文件夹中多了一个 doubanmovie250.py,它就是刚刚创建的 Spider,内容如下所示:

import scrapy
class DoubanSpider(scrapy.Spider):
    name = 'doubanmovie250'
    allowed_domains = ['douban.com']
    start_urls = ['http://douban.com/']
    def parse(self, response):
        pass

这里有三个属性————name、allowed_domainsstart_urls,还有一个方法 parse。

  • name,它是每个项目唯一的名字,用来区分不同的 Spider。
  • allowed_domains,它是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉。
  • start_urls,它包含了 Spider 在启动时爬取的 url 列表,初始请求是由它来定义的。
  • parse,它是 Spider 的一个方法。默认情况下,被调用时 start_urls 里面的链接构成的请求完成下载执行后,返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。由于我们要爬取的是top250电影信息,所以需要将 start_urls 修改为 ['https://movie.douban.com/top250']修改后的代码如下所示:
import scrapy
class DoubanSpider(scrapy.Spider):
    name = 'doubanmovie250'
    allowed_domains = ['douban.com']
    start_urls = ['https://movie.douban.com/top250']
    def parse(self, response):
        pass

3.创建 Item

Item 是保存爬取数据的容器,它的使用方法和字典类似。创建 Item 需要继承 scrapy.Item 类,并且定义类型为 scrapy.Field 的字段,我们可以获取到的内容有rank、title、rating、country、genre、release_timedirector_actor。将 items.py 修改如下:

import scrapy
class Doubanmovie250Item(scrapy.Item):
    # define the fields for your item here like:
    rank = scrapy.Field()
    title = scrapy.Field()
    rating = scrapy.Field()
    country = scrapy.Field()
    genre = scrapy.Field()
    release_time = scrapy.Field()
    director_actor = scrapy.Field()

这里定义了七个字段,接下来爬取时我们会使用到这个 Item。

4.解析 Response

前面我们看到,parse() 方法的参数 response 是 start_urls 里面的连接爬取后的结果。所以在 parse() 方法中,我们可以直接对 response 变量包含的内容进行解析。解析的方法使用的是第 6 节中的方法,所不同的是将解析的结果赋值给 Item 的每个字段。代码如下:

def parse(self, response):
        item = Doubanmovie250Item()
        soup = BeautifulSoup(response.text, 'lxml')
        ol = soup.ol
        all_li = ol.find_all('li')
        for li in all_li:
            item['rank'] = li.find('em', class_="").string
            item['title'] = li.find('span', class_="title").string
            item['rating'] = li.find('span', class_="rating_num").string
            info = li.find('div', class_="bd").p.get_text().strip()
            item['country'] = info.split('/')[-2]
            item['genre'] = info.split('/')[-1]
            item['release_time'] = info.split('\n')[1].split('/')[0].replace(" ", "")
            item['director_actor'] = li.find('div', class_="bd").p.next_element.replace(
                "\n", "").replace(" ", "")
            yield item

如此一来,首页的所有内容被解析出来,并被赋值成了一个个 Doubanmovie250Item。

5.后续 Request

上面的操作实现了从初始页面抓取内容。那么,下一页的内容该如何抓取?这就需要我们从当前页面中找到信息来生成下一个请求,然后在下一个请求的页面里找到信息再构造下一个请求。这样循环往复迭代,从而实现整站的爬取。通过分析页面我们发现,可以通过解析后页这个标签的内容来获取下一个要爬取的链接,如下图所示:

网络异常,图片无法展示
|

代码如下:

next = soup.find('span', class_='next').a
        if next:
            href = soup.find('span', class_='next').a['href']
            url = 'https://movie.douban.com/top250' + href
            yield scrapy.Request(url, callback=self.parse)

和解析代码合并后的完整代码如下所示:

def parse(self, response):
        item = Doubanmovie250Item()
        soup = BeautifulSoup(response.text, 'lxml')
        ol = soup.ol
        all_li = ol.find_all('li')
        for li in all_li:
            item['rank'] = li.find('em', class_="").string
            item['title'] = li.find('span', class_="title").string
            item['rating'] = li.find('span', class_="rating_num").string
            info = li.find('div', class_="bd").p.get_text().strip()
            item['country'] = info.split('/')[-2]
            item['genre'] = info.split('/')[-1]
            item['release_time'] = info.split('\n')[1].split('/')[0].replace(" ", "")
            item['director_actor'] = li.find('div', class_="bd").p.next_element.replace(
                "\n", "").replace(" ", "")
            yield item
        next = soup.find('span', class_='next').a
        if next:
            href = soup.find('span', class_='next').a['href']
            url = 'https://movie.douban.com/top250' + href
            yield scrapy.Request(url, callback=self.parse)

6.内容保存

由于我们想把爬取到的内容保存到 csv 文件,需要在 pipelines.py 文件中进行保存的操作。代码如下:

from itemadapter import ItemAdapter
import csv
class Doubanmovie250Pipeline:
    def open_spider(self, spider):
        self.file = open('top250.csv', 'w')
        self.writer = csv.writer(self.file, delimiter=',')
        self.writer.writerow(["排名", "名称", "评分", "国家", "类型", "上映时间", "导演&主演"])
    def close_spider(self, spider):
        self.file.close()
    def process_item(self, item, spider):
        self.writer.writerow([
            item['rank'],
            item['title'],
            item['rating'],
            item['country'],
            item['genre'],
            item['release_time'],
            item['director_actor']
        ])
        return item

上面代码在 open_spider 方法中打开一个文件,在 close_spider 方法中关闭打开的文件,并在 process_item 方法中进行数据的写文件操作。

7.运行

接下来,进入目录,运行如下命令:scrapy crawl doubanmovie250就可以看到 scrapy 的运行结果了。保存后的 csv 文件如下所示:

网络异常,图片无法展示
|

本篇文章只是通过一个实例了解使用 Scrapy 框架爬取数据的整个过程。当然,这只是 Scrapy 强大功能的冰山一角,更多的强大功能还需要小伙伴自己在实践中逐步掌握。

相关文章
|
1月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
83 6
|
2月前
|
数据采集 中间件 开发者
Scrapy爬虫框架-自定义中间件
Scrapy爬虫框架-自定义中间件
55 1
|
2月前
|
数据采集 中间件 Python
Scrapy爬虫框架-通过Cookies模拟自动登录
Scrapy爬虫框架-通过Cookies模拟自动登录
103 0
|
1月前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
61 4
|
2月前
|
数据采集 前端开发 数据处理
Scrapy的Lambda函数用法:简化数据提取与处理的技巧
在现代爬虫开发中,**Scrapy** 是一个广泛使用的高效 Python 框架,适用于大规模数据爬取。本文探讨如何利用 Python 的 **Lambda 函数** 简化 Scrapy 中的数据提取与处理,特别是在微博数据爬取中的应用。通过结合 **代理IP**、**Cookie** 和 **User-Agent** 设置,展示了实际用法,包括代码示例和优化技巧,以提高爬虫的稳定性和效率。使用 Lambda 函数能显著减少代码冗余,提升可读性,有效应对复杂的数据清洗任务。
|
2月前
|
消息中间件 数据采集 数据库
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
30 1
|
2月前
|
数据采集 中间件 数据挖掘
Scrapy 爬虫框架(一)
Scrapy 爬虫框架(一)
51 0
|
2月前
|
数据采集 XML 前端开发
Scrapy 爬虫框架(二)
Scrapy 爬虫框架(二)
49 0
|
1月前
|
数据采集 中间件 API
在Scrapy爬虫中应用Crawlera进行反爬虫策略
在Scrapy爬虫中应用Crawlera进行反爬虫策略
|
7月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据