scrapy 是一个为了爬取网络数据库,提取结构性数据而编写的一个大而全的应用框架,我们在该框架的基础上,只需要少量代码就能完成我们之前要做的爬虫需求。
安装
sudo pip install incremental==17.5.0
pip install scrapy -i https://pypi.doubanio.com/simple
如果我们用的是windows系统,安装过程将是十分的曲折。可能需要我们收先安装Twisted
(安装过程遍地是坑),然后再安装scrapy
。
windows系统下安装Scrapy
安装Twisted
打开网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted, 下载本机所装的Python版本对应的Twisted
。比如我的环境是64位系统,同时用的是python 3.6。那么理论上我下载的应该是64位版。但是,实际上我并没有安装成功。反倒是32位版安装成功了。
下载完该文件,我们把它放到D盘,该文件的路径就是:D:Twisted-18.9.0-cp36-cp36m-win32.whl
。该文件是已编译好的包。理论上我们可以直接安装。但是该包并不能直接识别,除非我们有wheel
包,因此我们需要先安装wheel
模块。
当然了。部分情况下有可能遇到pip版本过低引起的错误,更新一下版本就可以了:
python -m pip install --upgrade pip -i https://pypi.doubanio.com/simple
# 考虑到windows下可能遇到千奇百怪的问题,你可能需要用到强制更新
python -m pip install -U --force-reinstall pip -i https://pypi.doubanio.com/simple
安装 wheel
pip install wheel -i https://pypi.doubanio.com/simple
然后安装Twisted:
pip install D:Twisted-18.9.0-cp36-cp36m-win32.whl
这个过程我们可能会遇到这样的错误:
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
如果遇到这个问题,是因为Twisted
虽然是已经编译好的本地安装,但是安装的时候它依赖的其它包也要从网络中下载,这个可能因为网速的问题会导致超时。解决方式也比较简单,从两个方面做起吧,一个是增大超时时间,另一个是指定个更快的软件源。因此我们可以试试用这样的命令
pip install --default-timeout=1000 D:Twisted-18.9.0-cp36-cp36m-win32.whl -i https://pypi.doubanio.com/simple
再然后安装scrapy:
很多情况下,您可能需要(也可能不需要)先按装pywin32
pip install pywin32 -i https://pypi.doubanio.com/simple
如果以上没啥问题,我们终于可以安装Scrapy了。
pip install scrapy -i https://pypi.doubanio.com/simple
如果前面步骤没啥问题,这步应该能成功。
基本认识
Scrapy架构图(绿线是数据流向):
快速使用
创建项目
# ss 是我们自定义的项目名
scrapy startproject ss
创建完以后,我们可以看到如下目录结构:
目录说明:
scrapy.cfg 项目的主配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py 设置数据存储模板,用于结构化数据,如:Django的Model
pipelines 数据处理行为,如:一般结构化的数据持久化
settings.py 配置文件,如:递归的层数、并发数,延迟下载等
spiders 爬虫目录,如:创建文件,编写爬虫规则
创建爬虫
# 首先,我们要切换到我们的项目目录,也就是第一级的ss目录
cd ss
# 其中 imshusheng 为爬虫的名字; imshusheng.com 为爬虫的起始url,后期可以修改
scrapy genspider imshusheng imshusheng.com
如果没什么问题,这一步执行完,会在我们的ss/ss/spiders/
目录下生成一个名字为:imshusheng.py
的文件。这就是我们创建的爬虫。
我们打开这个文件我们会看到如下内容:
# -*- coding: utf-8 -*-
import scrapy
class ImshushengSpider(scrapy.Spider):
# 这是我们的爬虫名称
name = 'imshusheng'
# 允许爬取的范围
allowed_domains = ['imshusheng.com']
# 这是爬虫的起始地址(可自行修改)
start_urls = ['http://imshusheng.com/']
def parse(self, response):
pass
我们将parse
方法中的内容稍作更改:
def parse(self, response):
# print(dir(response))
print(response.text)
让爬虫跑起来
# 让我们创建的name为imshusheng的爬虫跑起来
scrapy crawl imshusheng
# 不显示日志的跑起来
scrapy crawl imshusheng --nolog
常用模块说明
使用爬虫的parse
方法提取数据
从前面的例子我们可以看到,每个爬虫里面的parse
方法就是爬虫给我们留的用来提取数据的一个回调方法。该方法中的response
参数里面放的就是爬虫获取到的相应对象,我们可以从该对象中分析提取出我们想要的数据。
使用xpath方法
def parse(self, response):
# xpath()会返回一个符合选择条件的 选择器(selector) 对象
lists = response.xpath("//div[@class='media-heading']/a")
item = {}
for i in lists:
item['title'] = i.xpath('./text()').extract_first()
item['href'] = i.xpath('./@href').extract_first()
yield item
# extract() 将对象列表的对象转成字符串
# extract_first() 将对象列表的第一个对象转成字符串
# print(i.xpath('./text()').extract())
# # 获取每个元素的文本内容
# print(i.xpath('./text()').extract_first())
# # 获取每个元素的href属性
# print(i.xpath('./@href').extract_first())
使用pipeline格式化数据
parse
方法的返回值会提交到我们的pipelines.py
中定义的类中,在类中我们可以对数据进行再次处理。不过,如果我们想用该功能,需要在项目的settings.py
配置文件中打开一个配置段:
ITEM_PIPELINES = {
# 这里可以配置多个管道,数字越小的管道 数据 越早经过
'ss.pipelines.SsPipeline': 300,
# 我们可以在pipelines.py中定义多个类,
#'ss.pipelines.SsPipeline0': 301,
}
我们看一下默认在pipelines.py
中为我们生成SsPipeline
类。
class SsPipeline(object):
# 这里的item就是我们爬虫为我们返回的数据
# spider 就是发送数据的爬虫对象,我们可以根据他的name值来判断数据来源于哪个爬虫
def process_item(self, item, spider):
print(spider.name)
# 如果希望传给下一个处理,要有return
return item
使用 scrapy.Request()构造请求
scrapy.Request('http://www.baidu.com', callback=self.parse)