大家好,我是m!

之前分享了很多 requests 、selenium 的 Python 爬虫文章,本文将从原理到实战带领大家入门另一个强大的框架 Scrapy。如果对Scrapy感兴趣的话,不妨跟随本文动手做一遍!

一、Scrapy框架简介

Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据,只需要实现少量的代码,就能够快速的抓取。

二、运行原理

Scrapy框架的运行原理看下面一张图就够了(事实上原理是比较复杂的,也不是三言两语能够说清楚的,因此感兴趣的读者可以进一步阅读更多的相关文章来了解,本文不做过多讲解)

Scrapy主要包括了以下组件:

引擎(Scrapy Engine) Item 项目 调度器(Scheduler) 下载器(Downloader) 爬虫(Spiders) 项目管道(Pipeline) 下载器中间件(Downloader Middlewares) 爬虫中间件(Spider Middlewares) 调度中间件(Scheduler Middewares)

三. 入门

3.1安装

第一种:在命令行模式下使用pip命令即可安装:

$ pip install scrapy

第二种:首先下载,然后再安装:

$ pip download scrapy -d ./

# 通过指定国内镜像源下载

$pip download -i https://pypi.tuna.tsinghua.edu.cn/simple scrapy -d ./

进入下载目录后执行下面命令安装:

$ pip install Scrapy-1.5.0-py2.py3-none-any.whl

3.2使用

使用大概分为下面四步 1 创建一个scrapy项目

scrapy startproject mySpider

2 生成一个爬虫

scrapy genspider demo "demo.cn"

3 提取数据

完善spider 使用xpath等

4 保存数据

pipeline中保存数据

3.3 程序运行

在命令中运行爬虫

scrapy crawl qb # qb爬虫的名字

在pycharm中运行爬虫

from scrapy import cmdline

cmdline.execute("scrapy crawl qb".split())

四、基本步骤

Scrapy 爬虫框架的具体使用步骤如下:

选择目标网站 定义要抓取的数据(通过Scrapy Items来完成的) 编写提取数据的spider 执行spider,获取数据 数据存储

五. 目录文件说明

当我们创建了一个scrapy项目后,继续创建了一个spider,目录结构是这样的:

下面来简单介绍一下各个主要文件的作用:

scrapy.cfg :项目的配置文件

mySpider/ :项目的Python模块,将会从这里引用代码

mySpider/items.py :项目的目标文件

mySpider/pipelines.py :项目的管道文件

mySpider/settings.py :项目的设置文件

mySpider/spiders/ :存储爬虫代码目录

5.1 scrapy.cfg文件

项目配置文件。这个是文件的内容:

# Automatically created by: scrapy startproject

#

# For more information about the [deploy] section see:

# https://scrapyd.readthedocs.io/en/latest/deploy.html

[settings]

default = mySpider.settings

[deploy]

#url = http://localhost:6800/

project = mySpider

5.2 mySpider

项目的Python模块,将会从这里引用代码

5.3 mySpider/items.py

项目的目标文件

# Define here the models for your scraped items

#

# See documentation in:

# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

class MyspiderItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

pass

定义scrapy items的模块,示例: name = scrapy.Field()

5.4 mySpider/pipelines.py

项目的管道文件

# Define your item pipelines here

#

# Don't forget to add your pipeline to the ITEM_PIPELINES setting

# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html

# useful for handling different item types with a single interface

from itemadapter import ItemAdapter

class MyspiderPipeline:

def process_item(self, item, spider):

return item

这个文件也就是我们说的管道,当Item在Spider中被收集之后,它将会被传递到Item Pipeline(管道),这些Item Pipeline组件按定义的顺序处理Item。每个Item Pipeline都是实现了简单方法的Python类,比如决定此Item是丢弃而存储。以下是item pipeline的一些典型应用:

验证爬取的数据(检查item包含某些字段,比如说name字段) 查重(并丢弃) 将爬取结果保存到文件或者数据库中

5.5 mySpider/settings.py

项目的设置文件

# Scrapy settings for mySpider project

...

BOT_NAME = 'mySpider' # scrapy项目名

SPIDER_MODULES = ['mySpider.spiders']

NEWSPIDER_MODULE = 'mySpider.spiders'

.......

# Obey robots.txt rules

ROBOTSTXT_OBEY = False # 是否遵守协议,一般给位false,但是创建完项目是是True,我们把它改为False

# Configure maximum concurrent requests performed by Scrapy (default: 16)

#CONCURRENT_REQUESTS = 32 # 最大并发量 默认16

......

#DOWNLOAD_DELAY = 3 # 下载延迟 3秒

# Override the default request headers: # 请求报头,我们打开

DEFAULT_REQUEST_HEADERS = {

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

'Accept-Language': 'en',

}

# 爬虫中间件

#SPIDER_MIDDLEWARES = {

# 'mySpider.middlewares.MyspiderSpiderMiddleware': 543,

#}

# 下载中间件

#DOWNLOADER_MIDDLEWARES = {

# 'mySpider.middlewares.MyspiderDownloaderMiddleware': 543,

#}

......

# Configure item pipelines

# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html

#ITEM_PIPELINES = {

# 'mySpider.pipelines.MyspiderPipeline': 300, # 管道

#}

.......

省略号省略代码,一般重要点,给了注释

6.mySpider/spiders/ :存储爬虫代码目录

import scrapy

class DbSpider(scrapy.Spider):

name = 'db'

allowed_domains = ['douban.com'] # 可以修改

start_urls = ['http://douban.com/'] # 开始的url也可以修改

def parse(self, response):

# pass

六. Scrapy shell

Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据,但是一般使用的不多。感兴趣的查看官方文档:

官方文档

http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/shell.html

Scrapy Shell根据下载的页面会自动创建一些方便使用的对象,例如 Response 对象,以及 Selector 对象 (对HTML及XML内容)。

当shell载入后,将得到一个包含response数据的本地 response 变量,输入 response.body将输出response的包体,输出 response.headers 可以看到response的包头。 输入 response.selector 时, 将获取到一个response 初始化的类 Selector 的对象,此时可以通过使用 response.selector.xpath()或response.selector.css() 来对 response 进行查询。 Scrapy也提供了一些快捷方式, 例如 response.xpath()或response.css()同样可以生效(如之前的案例)。

Selectors选择器

Scrapy Selectors 内置 XPath 和 CSS Selector 表达式机制

Selector有四个基本的方法,最常用的还是xpath:

xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 extract(): 序列化该节点为字符串并返回list css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表,语法同 BeautifulSoup4 re(): 根据传入的正则表达式对数据进行提取,返回字符串list列表

七、案例实战

本节,我将使用Scrapy爬取站酷数据作为示例

7.1 案例说明

既然已经初步了解了scrapy的工作流程以及原理,我们来做一个入门的小案例,爬取站酷首页推荐的item信息。如下图所示,一个小方框就是一个item信息。我们要提取每一个item的六个组成部分:

imgLink(封面图片链接); title(标题); types(类型); vistor(人气); comment(评论数); likes(推荐人数)

然后只是一个页面的item,我们还要通过翻页实现批量数据采集。

7.2 文件配置

目录结构

在上一篇中我们说明了新建scrapy项目(zcool)和spider项目(zc),这里不再赘述,然后得到我们的目录结构如下图所示:

start.py文件

然后为了方便运行,在zcool目录下新建start文件。并进行初始化设置。

from scrapy import cmdline

cmdline.execute('scrapy crawl zc'.split())

settings.py文件

在这个文件里我们需要做几样设置

避免在程序运行的时候打印log日志信息

LOG_LEVEL = 'WARNING'

ROBOTSTXT_OBEY = False

添加请求头:

打开管道:

item.py文件

import scrapy

class ZcoolItem(scrapy.Item):

# define the fields for your item here like:

imgLink = scrapy.Field() # 封面图片链接

title = scrapy.Field() # 标题

types = scrapy.Field() # 类型

vistor = scrapy.Field() # 人气

comment = scrapy.Field() # 评论数

likes = scrapy.Field() # 推荐人数

7.3 页面数据提取

首先我们在站酷页面使用xpath-helper测试一下:

然后zc.py文件里面初步测试一下:

def parse(self, response):

divList = response.xpath('//div[@class="work-list-box"]/div')

print(len(divList))

运行结果如下图所示:

没有问题,然后我们对各种信息分别解析提取,

def parse(self, response):

divList = response.xpath('//div[@class="work-list-box"]/div')

for div in divList:

imgLink = div.xpath("./div[1]/a/img/@src").extract()[0] # 1.封面图片链接

... 2.title(标题);3 types(类型);4vistor(人气);5comment(评论数) ....

likes = div.xpath("./div[2]/p[3]/span[3]/@title").extract_first() # 6likes(推荐人数)

item = ZcoolItem(imgLink=imgLink,title=title,types=types,vistor=vistor,comment=comment,likes=likes)

yield item

解释: xpath提取数据方法:

S.N.方法 & 描述extract()返回的是符合要求的所有的数据,存在一个列表里。extract_first()返回的hrefs 列表里的第一个数据。get()和extract_first()方法返回的是一样的,都是列表里的第一个数据。getall()和extract()方法一样,返回的都是符合要求的所有的数据,存在一个列表里。

注意:

get() 、getall() 方法是新的方法,extract() 、extract_first()方法是旧的方法。extract() 、extract_first()方法取不到就返回None。get() 、getall() 方法取不到就raise一个错误。

item实例创建(yield上面一行代码)

这里我们之前在目录文件配置的item文件中已经进行了设置,对于数据存储,我们在爬虫文件中开头要导入这个类:

from zcool.items import ZcoolItem

然后使用yield返回数据。

为什么使用yield而不是return

不能使用return这个无容置疑,因为要翻页,使用return直接退出函数;而对于yield:在调用for的时候,函数内部不会立即执行,只是返回了一个生成器对象。在迭代的时候函数会开始执行,当在yield的时候,会返回当前值(i)。之后的这个函数会在循环中进行,直到没有下一个值。

7.4 翻页实现批量数据采集

通过上面的代码已经可以初步实现数据采集,只不过只有第一页的,如下图所示:

但是我们的目标是100个页面的批量数据采集,所以代码还需要修改。针对翻页这里介绍两种方式:

方式一:我们首先在页面中定位到下一页的按钮,如下图所示:

然后编写如下代码,在for循环完毕后。

next_href = response.xpath("//a[@class='laypage_next']/@href").extract_first()

if next_href:

next_url = response.urljoin(next_href)

print('*' * 60)

print(next_url)

print('*' * 60)

request = scrapy.Request(next_url)

yield request

scrapy.Request(): 把下一页的url传递给Request函数,进行翻页循环数据采集。

https://www.cnblogs.com/heymonkey/p/11818495.html # scrapy.Request()参考链接

注意方式一只有下一页按钮它的href对应属性值和下一页的url一致才行。

方式二:定义一个全局变量count = 0,每爬取一页数据,令其加一,构建新的url,再使用scrapy.Request() 发起请求。

如下图所示:

count = 1

class ZcSpider(scrapy.Spider):

name = 'zc'

allowed_domains = ['zcool.com.cn']

start_urls = ['https://www.zcool.com.cn/home?p=1#tab_anchor'] # 第一页的url

def parse(self, response):

global count

count += 1

for div in divList:

# ...xxx...

yield item

next_url = 'https://www.kuaikanmanhua.com/tag/0?state=1&sort=1&page={}'.format(count)

yield scrapy.Request(next_url)

这两种方式在实际案例中择机采用。

7.5 数据存储

数据存储是在pipline.py中进行的,代码如下:

from itemadapter import ItemAdapter

import csv

class ZcoolPipeline:

def __init__(self):

self.f = open('Zcool.csv','w',encoding='utf-8',newline='') # line1

self.file_name = ['imgLink', 'title','types','vistor','comment','likes'] # line2

self.writer = csv.DictWriter(self.f, fieldnames=self.file_name) # line3

self.writer.writeheader() # line4

def process_item(self, item, spider):

self.writer.writerow(dict(item)) # line5

print(item)

return item # line6

def close_spider(self,spider):

self.f.close()

解释:

line1: 打开文件,指定方式为写,利用第3个参数把csv写数据时产生的空行消除 line2: 设置文件第一行的字段名,注意要跟spider传过来的字典key名称相同 line3: 指定文件的写入方式为csv字典写入,参数1为指定具体文件,参数2为指定字段名 line4: 写入第一行字段名,因为只要写入一次,所以文件放在__init__里面 line5: 写入spider传过来的具体数值,注意在spider文件中yield的item,是一个由类创建的实例对象,我们写入数据时,写入的是 字典,所以这里还要转化一下。 line6: 写入完返回

7.6 程序运行

因为之前创建了start.py文件,并且对它就行了初始化设置,现在运行爬虫程序不需要在控制台中输入命令:

scrapy crawl zc(爬虫项目名)

直运行start.py文件:得到如下结果:

对应于页面:

打开csv文件如下图所示:(由于csv文件在word中乱码了,此处我是用Notepad++打开)

没有问题,数据采集完毕。

7.7. 总结

入门案例,需要细心,主要是基础知识的巩固,以便于为进阶学习做好准备。

我准备了一些非常系统的Python学习资料,除了为你提供一条清晰、无痛的学习路径,还甄选了最实用的学习资源以及庞大的主流爬虫案例库。短时间的学习,你就能够很好地掌握Python这个技能,获取你想得到的数据,需要的朋友可以扫描文末二维码即可获取。

01 专为0基础设置,小白也能轻松学会

我们把Python的所有知识点,都穿插在了漫画里面。

在Python小课中,你可以通过漫画的方式学到知识点,难懂的专业知识瞬间变得有趣易懂。

你就像漫画的主人公一样,穿越在剧情中,通关过坎,不知不觉完成知识的学习。

02 无需自己下载安装包,提供详细安装教程

03 规划详细学习路线,提供学习视频

04 提供实战资料,更好巩固知识

05 提供面试资料以及副业资料,便于更好就业

这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要也可以扫描下方csdn官方二维码或者点击主页和文章下方的微信卡片获取领取方式,【保证100%免费】

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: