简介
- Scrapy是⽤纯Python实现⼀个为了爬取⽹站数据、提取结构性数据⽽编写的应⽤框架,⽤途⾮常⼴泛。
- 框架的⼒量,⽤户只需要定制开发⼏个模块就可以轻松的实现⼀个爬
⾍,⽤来抓取⽹⻚内容以及各种图⽚,⾮常之⽅便。- Scrapy使⽤了Twisted ['twɪstɪd] (其主要对⼿是Tornado)异步⽹络框架来处理⽹络通讯,可以加快我们的下载速度,不⽤⾃⼰去实现异步框架,并且包含了各种中间件接⼝,可以灵活的完成各种需求。
架构图

安装
- 打开PyCharm,在Termminal中输入
pip3 install Scrapy
Scrapy
执行Scrapy出现一下结果说明安装成功
Scrapy 2.4.0 - no active project
Usage:
scrapy <command> [options] [args]
Available commands:
bench Run quick benchmark test
commands
fetch Fetch a URL using the Scrapy downloader
genspider Generate new spider using pre-defined templates
runspider Run a self-contained spider (without creating a project)
settings Get settings values
shell Interactive scraping console
startproject Create new project
version Print Scrapy version
view Open URL in browser, as seen by Scrapy
[ more ] More commands available when run from project directory
- 安装成功之后,在PyCharm中新建项目spiderweb,在Termminal中cd到目标目录,执行下面命令:

cd /Users/***/spiderweb
步骤
- 新建项⽬(scrapy startproject ***):新建⼀个新的爬⾍项⽬
在目标文件夹中:
scrapy startproject mySpider

目录简介
scrapy.cfg:项⽬的配置⽂件
mySpider/:项⽬的Python模块,将会从这⾥引⽤代码mySpider/items.py:项⽬的⽬标⽂件
mySpider/pipelines.py:负责处理Spider中获取的Item,并经行后期处理(详细分析、过滤、存储等)的地方
mySpider/items.py:项⽬的设置⽂件,这是创建容器的地方,爬取的信息分别放到不同容器里
mySpider/settings.py:项⽬的设置⽂件
mySpider/spiders/:存储爬⾍代码⽬录
- 制作爬⾍(spiders/xxspider.py):制作爬⾍开始爬取⽹⻚
我们以获取百度首页的标题为例,切换到spider目录夹下,执行一下命令:
scrapy genspider baidu "baidu.com"
自动生成爬虫脚本:

import scrapy
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
def parse(self, response):
pass
参数说明
name="":这个爬⾍的识别名称,必须是唯⼀的,在不同的爬⾍必须定义不同的名字。必需保持跟文件名一致,否则会报错
allow_domains=[]:是搜索的域名范围,也就是爬⾍的约束区域,规定爬⾍只爬取这个域名下的⽹⻚,不存在的URL会被忽略。
start_urls=():爬取的URL元祖/列表。爬⾍从这⾥开始抓取数据,所以,第⼀次下载的数据将会从这些urls开始。其他⼦URL将会从这些起始URL中继承性⽣成。
parse(self,response):解析的⽅法,每个初始URL完成下载后将被调⽤,调⽤的时候传⼊从每⼀个URL传回的Response对象来作为唯⼀参数,主要作⽤如下:
- 负责解析返回的⽹⻚数据(response.body),提取结构化数据(⽣成item)
- ⽣成需要下⼀⻚的请求URL。
response 返回含义
url :HTTP响应的url地址,str类型
status:HTTP响应的状态码, int类型
headers :HTTP响应的头部, 类字典类型, 可以调用get或者getlist方法对其进行访问
body:HTTP响应正文, bytes类型
text:文本形式的HTTP响应正文, str类型
encoding:HTTP响应正文的编码
response.text = response.body.decode(response.encoding)
reqeust:产生该HTTP响应的Reqeust对象
meta:即response.request.meta, 在构造Request对象时, 可将要传递给响应处理函数的信息通过meta参数传入, 响应处理函数处理响应时, 通过response.meta将信息提取出来
selector:Selector对象用于在Response中提取数据使用下面详细将,主要是 xpath,css取值之后的处理
urljoin(url) :用于构造绝对url, 当传入的url参数是一个相对地址时, 根据response.url计算出相应的绝对url.
xpath(query):获取制定标签内容
css(query) :获取制定css样式内容
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
def parse(self, response):
title = response.xpath('//title//text()').extract()[0]
print("网页标题:"+title)
pass
注意:不能在PyCharm中直接运行,需要用命令启动Scrapy爬虫

在运行项目之前,记得关闭setting.py中的遵守爬虫协议

# Obey robots.txt rules
ROBOTSTXT_OBEY = False
在Termminal中输入
scrapy crawl baidu
项目测试,当出现以下内容时,表示获取网页标题内容成功:

- 明确⽬标(编写items.py):明确你想要抓取的⽬标
这里先考虑抓取网页标题
class MyspiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 爬取网页的标题
title = scrapy.Field()
pass
获取值之后往item中塞入值,通过yield结束
import scrapy
from ..items import MyspiderItem
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
def parse(self, response):
title = response.xpath('//title//text()').extract()[0]
print("网页标题:"+title)
item = MyspiderItem()
item['title'] = title
yield item
注意 item['title']中的'title'必需MyspiderItem 中的title保持一致
- 存储内容(pipelines.py):设计管道存储爬取内容
当Item在Spider中被收集之后,它将会被传递到ItemPipeline,这些Item
Pipeline组件按定义的顺序处理Item。
每个ItemPipeline都是实现了简单⽅法的Python类,⽐如决定此Item是丢弃⽽存储。以下是itempipeline的⼀些典型应⽤:
- 验证爬取的数据(检查item包含某些字段,⽐如说title字段);
- 查重(并丢弃)将爬取结果保存到文件或者数据库中;
这里将爬虫结果保存成json格式:
import json
class MyspiderPipeline:
def __init__(self):
# 可选实现,做参数初始化等
# doing something
self.f = open('baiduSpider.json', 'wb')
def process_item(self, item, spider):
# item (Item 对象) – 被爬取的item
# spider (Spider 对象) – 爬取该item的spider
# 这个方法必须实现,每个item pipeline组件都需要调用该方法,
# 这个方法必须返回一个 Item 对象,被丢弃的item将不会被之后的pipeline组件所处理。
result = json.dumps(dict(item), ensure_ascii=False)
self.f.write(result.encode('utf-8'))
# 将Item返回至引擎,告知该item已经处理完成,你可以给我下一个item
return item
def open_spider(self, spider):
# spider (Spider 对象) – 被开启的spider
# 可选实现,当spider被开启时,这个方法被调用。
pass
def close_spider(self, spider):
# spider (Spider 对象) – 被关闭的spider
# 可选实现,当spider被关闭时,这个方法被调用
self.f.close()
启用一个Item Pipeline组件,为了启用Item Pipeline组件,必须将它的类添加到 settings.py文件ITEM_PIPELINES 配置,就像下面这个例子:

必需启动Item Pipeline组件
ITEM_PIPELINES = {
#根据自己的类名路径填写
'mySpider.pipelines.MyspiderPipeline': 300,
}
分配给每个类的整型值,确定了他们运行的顺序,item按数字从低到高的顺序,通过pipeline,通常将这些数字定义在0-1000范围内(0-1000随意设置,数值越低,组件的优先级越高)
重新执行命令,爬取成功之后会出现相应的json和内容:
scrapy crawl baidu

总结
一个简单的Python+PyCharm +Scrapy项目就构建成了,这里PyCharm只是作为一个代码编辑器,项目的新建、构造、运行都是通过命令行实现,后面我们可以处理更为复杂的网站数据,也可以对数据进行处理之后数据存储到数据库中。
网友评论