Python爬虫深造篇(四)——Scrapy爬虫框架启动一个真正的项目

一、前情提要

经过前面的学习,我们初识了 Scrapy 框架,通过 Scrapy 提供的互动工具,我们在命令行中体验了 Scrapy 中的 CSS 选择器

最重要的几个点是:. 代表 class,# 代表 id,比如 div.book 代表 class 包含 book 的 div 元素,div#book 代表 id 为 book 的 div 元素。在有层级关系时,用 > 号连接直接下一级的元素,用空格连接所有下级的元素。

这篇文章将带大家将走进 Scrapy,学习如何启动一个真正意义上的 Scrapy 项目。

二、走进scrapy

和之前一样,我们 Win + R 打开 cmd 命令行,在命令行输入 scrapy 检查框架是否正常显示,然后我们再输入explorer . 打开执行命令所在的文件夹↓

注意:explorer 命令后面有一个点,这个点代表当前文件夹,同时要注意 explorer 命令和点之间有一个空格。

在这里插入图片描述
之后在命令行中输入下面的命令,让 Scrapy 创建一个名叫 appinn 项目:

scrapy startproject appinn

在这里插入图片描述
这时你会发现刚刚打开的文件夹里多了一个叫做 appinn 的文件夹,它的目录结构如下:

appinn
├── appinn         # 项目代码所在的目录
│   ├── __init__.py
│   ├── items.py     # 定义数据的格式
│   ├── middlewares.py
│   ├── pipelines.py   # 处理数据、输出到文件等等
│   ├── settings.py    # 一些设置
│   └── spiders      # 爬虫所在的目录
│       └── __init__.py
└── scrapy.cfg

在这里插入图片描述
上面标红的就是需要大家留心的!
然后我们还需要在命令行里输入 cd appinn,进入 appinn 文件夹。
在这里插入图片描述

注意:下面的操作都需要保证命令行在项目里哦,如果出错,请先检查一下自己是不是在项目根目录里。

下面我们来跟随一个简单的项目实战,理解这些文件的作用
我们打开小众软件的 Windows 软件推荐页:https://www.appinn.com/category/windows/
在这里插入图片描述
然后随便打开一篇文章
这次我们要爬取的是 Windows 版面下所有文章的标题、时间、作者、分数、正文↓
在这里插入图片描述
接下来,我们来分别看看 Scrapy 生成的这些文件在爬虫中具体起到了什么作用。

1、items.py

items.py 是记录我们想要的数据格式的文件。

在确定了我们要爬的数据是什么之后,就可以来定义数据的格式。我们数据的格式可以定义在 items.py 里。创建项目时 Scrapy 给这个文件自动生成了如下的代码↓
我们利用编辑器打开 items.py 文件

import scrapy

class AppinnItem(scrapy.Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  pass

按照我们需要的数据标题、时间、作者、分数、正文,分别把他们叫做 title、time、author、score 和 content。于是把 items.py 文件里的代码改成这样↓

import scrapy

class Article(scrapy.Item):
  title = scrapy.Field()  # 标题
  time = scrapy.Field()   # 时间
  author = scrapy.Field()   # 作者
  score = scrapy.Field()  # 分数
  content = scrapy.Field()  # 内容

通过 scrapy.Field() 方法,我们定义出了所有需要的字段,这样就定义好了我们要的数据格式:一个叫做 Article 的 Item。Item 是一个和字典类似的东西,使用它而不用字典的理由就是:在爬取网页的时候常常出现数据缺失、内容错误之类的问题,使用 Item 可以更好的处理这些问题。

2、spiders 目录

spiders 目录里保存了我们创建的爬虫。

在命令行里执行下面的命令并回车,它会帮我们创建一个叫做 article 的爬虫,并且只爬取 www.appinn.com 下的网页↓

scrapy genspider article www.appinn.com

在这里插入图片描述
执行成功后可以看到在 spiders 目录里多出了一个 article.py,文件里有自动生成的代码↓

import scrapy

class ArticleSpider(scrapy.Spider):
  name = 'article'
  allowed_domains = ['www.appinn.com']
  start_urls = ['http://www.appinn.com/']

  def parse(self, response):
    pass

注意👇
name :是项目中每个爬虫唯一的名字,用来区分不同的爬虫。
allowed_domains :是允许爬取的域名,如果请求的链接不在这个域名下,那么这些请求将会被过滤掉。
start_urls :是初始请求地址的列表,也就是一开始就爬取的页面地址列表。
parse() :方法是默认的解析方法,负责解析返回的响应、提取数据或者生成下一步要处理的请求。

现在我先把代码进行拆分说明!后面会有完整代码!

首先我们把 start_urls 改成我们需要的开始链接↓

start_urls = ['https://www.appinn.com/category/windows/']

接着引入我们刚刚写好的 Items.py↓

from appinn.items import Article

下面是加一个解析文章的方法,用来解析文章详情页(如:https://www.appinn.com/videocutter-and-mp3cutter-yyzsoft/),把标题、时间、作者、分数、正文取出来。我们把这个方法叫做 parse_article,具体代码如下↓

def parse_article(self, response):
  article = Article()
  # 从 response 里提取出标题、时间、作者、分数和内容
  # 并将它们都存到 article 这个 item 里
  article['title'] = response.css('h1.title::text').get()
  article['time'] = response.css('span.thetime span::text').get()
  article['author'] = response.css('span.theauthor span a::text').get()
  article['score'] = response.css('em strong::text').get()
  contents = response.css('div.post-single-content *::text').getall()
  article['content'] = '\n'.join(contents)
  # 给出结果
  yield article

注意:上一篇中我们介绍过 yield,它和 return 类似,但不会结束函数或方法,而能够多次返回内容。

然后是默认的解析方法 parse(),我们用它来解析列表页↓

def parse(self, response):
  # 找到所有文章的链接,通知 Scrapy 用 parse_article 方法解析
  for article_url in response.css('article h2.title a::attr(href)').getall():
    if not article_url:
      continue
    # 后续请求和解析
    yield response.follow(article_url, self.parse_article)

  # 找到下一页的链接,通知 Scrapy 用 parse 方法解析
  next_page = response.css('a.next::attr(href)').get()
  if next_page:
    # 后续请求和解析
    yield response.follow(next_page, self.parse)

response.follow() 方法用于生成下一个请求和数据解析,第一个参数是下一个页面的地址,第二个是用于解析从第一个参数地址获取到网页源代码数据的方法。上面解析文章用了 parse_article() 方法,解析文章列表页用了 parse() 方法。

到这里,我们 spiders 目录里的爬虫就写好了。完整版的 article.py 如下↓

import scrapy
from appinn.items import Article

class ArticleSpider(scrapy.Spider):
  name = 'article'
  allowed_domains = ['www.appinn.com']
  start_urls = ['https://www.appinn.com/category/windows/']

  def parse(self, response):
    # 找到所有文章的链接,通知 Scrapy 用 parse_article 方法解析
    for article_url in response.css('article h2.title a::attr(href)').getall():
      if not article_url:
        continue
      # 后续请求和解析
      yield response.follow(article_url, self.parse_article)

    # 找到下一页的链接,通知 Scrapy 用 parse 方法解析
    next_page = response.css('a.next::attr(href)').get()
    if next_page:
      # 后续请求和解析
      yield response.follow(next_page, self.parse)

  def parse_article(self, response):
    article = Article()
    # 从 response 里提取出标题、时间、作者、分数和内容
    # 并将它们都存到 article 这个 item 里
    article['title'] = response.css('h1.title::text').get()
    article['time'] = response.css('span.thetime span::text').get()
    article['author'] = response.css('span.theauthor span a::text').get()
    article['score'] = response.css('em strong::text').get()
    contents = response.css('div.post-single-content *::text').getall()
    article['content'] = '\n'.join(contents)
    # 给出结果
    yield article

parse() 方法每次执行时都要完成下面这两件事↓
找到当前页面中所有文章的链接,生成解析请求,Scrapy 会用 parse_article() 方法解析文章链接;
找到下一个页面的链接,生成解析请求,Scrapy 会用 parse() 方法解析它找到的文章列表链接。

3、pipelines.py

pipelines.py 文件允许我们在得到结果之后,对结果进行一些处理。比如我们不想要分数在 3 以下的文章,就可以在 pipelines.py 里面做处理。

Scrapy 替我们自动生成的代码如下,默认会直接 return item,意思是保留所有的 item↓

class AppinnPipeline(object):
  def process_item(self, item, spider):
    return item

这个 process_item() 方法就是得到结果之后处理 item 的方法,在这里做一些过滤或者对 item 做一些修改都是可以的。在这个方法里 raise DropItem() 可以去掉我们不想要的 item,所以我们把它改成下面这样来去掉 3 分以下的文章↓

from scrapy.exceptions import DropItem

class AppinnPipeline(object):
  def process_item(self, item, spider):
    if item.get('score'):
      # 把 item 的 score 变成整数
      item['score'] = int(item['score'])
      if item['score'] < 3:
        raise DropItem('去掉 3 分以下的文章')
    return item

前面说过 item 和字典类似,你可以简单的认为 item 就是字典,使用 get() 方法可以获取其中的内容。当该键不存在时返回 None,而非报错。

4、settings.py

settings.py 是整个项目的配置文件,这个文件里可以设置爬取并发个数、等待时间、输出格式、默认 headers 等等。

我们可以写一些配置如下↓

BOT_NAME = 'appinn'

SPIDER_MODULES = ['appinn.spiders']
NEWSPIDER_MODULE = 'appinn.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'appinn (+http://www.yourdomain.com)'
# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# 上面都是自动生成的,下面开始是我们自己定义的
# 要使用的 pipeline
ITEM_PIPELINES = {
  'appinn.pipelines.AppinnPipeline': 300,  # 300 表示顺序,pipeline 有多个时,数字越小越先执行
}
FEED_FORMAT = 'csv'  # 最后输出的文件格式
FEED_URI = 'appin_windows_apps.csv'  # 最后输出的文件名

# 为了避免对被爬网站造成太大的压力,我们启动自动限速,设置最大并发数为 5
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_TARGET_CONCURRENCY = 5

5、执行爬取

在命令行输入 scrapy crawl article 并回车,爬虫就开始运行了。由于我们在设置文件里配置了自动限速,所以我们稍等几分钟。
在这里插入图片描述
自动爬取过程↓
在这里插入图片描述

完成后我们可以在命令行里输入 explorer . 打开当前所在的 appinn 文件夹,这时我们可以找到一个名为 appin_windows_apps.csv 的文件,这就是最后的结果↓
在这里插入图片描述

本次分享到此结束,谢谢大家阅读!!

  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何壹时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值