scrapy 是一个为了爬取网络数据库,提取结构性数据而编写的一个大而全的应用框架,我们在该框架的基础上,只需要少量代码就能完成我们之前要做的爬虫需求。
安装
sudo pip install incremental==17.5.0pip 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的Modelpipelines 数据处理行为,如:一般结构化的数据持久化settings.py 配置文件,如:递归的层数、并发数,延迟下载等spiders 爬虫目录,如:创建文件,编写爬虫规则
创建爬虫
# 首先,我们要切换到我们的项目目录,也就是第一级的ss目录cd ss# 其中 imshusheng 为爬虫的名字; imshusheng.com 为爬虫的起始url,后期可以修改scrapy genspider imshusheng imshusheng.com
如果没什么问题,这一步执行完,会在我们的ss/ss/spiders/
目录下生成一个名字为:imshusheng.py
的文件。这就是我们创建的爬虫。
我们打开这个文件我们会看到如下内容:
# -*- coding: utf-8 -*-import scrapyclass 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)