框架:具有很强的通用性,且封装了一些通用实现方法的项目模板
scrapy(异步框架):
高性能的网络请求
高性能的数据解析
高性能的持久化存储
高性能的全站数据爬取
高性能的深度爬取
高性能的分布式
Scrapy环境安装 IOS和Linuxpip install scrapy
windows a. pip3 install wheel b. 下载twisted ~gohlke/pythonlibs/#twisted # Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl; Python是3.5版本的就选择cp35下载 c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl # 安装失败可能是这个文件的版本导致的,即使Python版本都是对的,可以重新下载一个32位的试试 # 还安装失败的话就下载其python版本的,总有一个能成功 d. pip3 install pywin32 e. pip3 install scrapy安装完成后,输入``scrapy`测试一下,出现如下图显示,即安装成功。
scrapy startprojct proNmame
cd proNmame进入到工程目录下执行爬虫文件
proName # 工程名字 spiders # 爬虫包(文件夹) __init__.py __init__.py items.py middlewares.py pipelines.py settings.py # 创建好的工程的配置文件 scrapy.cfg # scrapy的配置文件,不用修改 创建爬虫文件创建爬虫文件是py源文件
scrapy genspider spiderName 网址后期可以修改
在spiders包下创建一个py文件
# -*- coding: utf-8 -*- import scrapy class FirstSpider(scrapy.Spider): # scrapy.Spider所有爬虫类的父类 # name表示的爬虫文件的名称,当前爬虫文件的唯一标识 name = \'first\' # 允许的域名,通常会注释掉 # allowed_domains = [\'www.xx.com\'] # 起始的url列表,最开始要爬的网址列表 # 作用:可以将内部的列表元素进行get请求的发送 start_urls = [\'http://www.sougou.com/\',\'www.baidu.com\'] # 调用parse方法解析数据,方法调用的次数由start_urls列表元素个数决定的 def parse(self, response): # response表示一个响应对象, pass 基本配置
UA伪装
robots协议的不遵从
在settings.py中将ROBOTSTXT_OBEY = True修改为False
指定日志等级
在settings.py中添加LOG_LEVEL = \'ERROR\'
执行工程
scrapy crawl spiderName
执行工程是不展示日志文件
scrapy crawl spiderName --nolog
这种方式下程序报错,不会展示;设置好日志等级后直接执行工程即可。
数据解析
response.xpath(\'xpath表达式\')
与etree的不同之处:
取文本/属性:返回的是一个Selector对象,文本数据是存储在该对象中
Selector对象[0].extract()返回字符串
Selector对象.extract_first()返回字符串
Selector对象.extract()返回列表
常用操作如果列表只有一个元素用Selector对象.extract_first(),返回字符串
如果列表有多个元素Selector对象.extract(),返回列表,列表里装的是字符串
spiderName.py文件
# -*- coding: utf-8 -*- import scrapy class DuanziSpider(scrapy.Spider): name = \'duanzi\' # allowed_domains = [\'www.xx.com\'] start_urls = [\'https://duanziwang.com/\'] def parse(self, response): article_list = response.xpath(\'/html/body/section/div/div/main/article\') # 基于xpath表达式解析 for article in article_list: title = article.xpath(\'./div[1]/h1/a/text()\')[0] # 返回一个Selector对象 # <Selector xpath=\'./div[1]/h1/a/text()\' data=\'关于健康养生、延年益寿的生活谚语_段子网收录最新段子\'> title = article.xpath(\'./div[1]/h1/a/text()\')[0].extract() # 返回字符串 # 关于健康养生、延年益寿的生活谚语_段子网收录最新段子 title = article.xpath(\'./div[1]/h1/a/text()\').extract_first() # 返回字符串 # 关于健康养生、延年益寿的生活谚语_段子网收录最新段子 title = article.xpath(\'./div[1]/h1/a/text()\').extract() # 返回列表 # [\'关于健康养生、延年益寿的生活谚语_段子网收录最新段子\'] print(title) break 持久化存储 基于终端指令的持久化存储
只可以将parse方法的返回值存储到指定后缀的文本文件中
指定后缀:\'json\', \'jsonlines\', \'jl\', \'csv\', \'xml\', \'marshal\', \'pickle\',通常用csv
指令scrapy crawl spiderName -o filePath
案例:将文本数据持久化存储 # -*- coding: utf-8 -*- import scrapy class DuanziSpider(scrapy.Spider): name = \'duanzi\' # allowed_domains = [\'www.xx.com\'] start_urls = [\'https://duanziwang.com/\'] # 基于终端指令的持久化存储 def parse(self, response): article_list = response.xpath(\'/html/body/section/div/div/main/article\') # 基于xpath表达式解析 all_data = [] for article in article_list: title = article.xpath(\'./div[1]/h1/a/text()\').extract_first() content = article.xpath(\'./div[2]/p//text()\').extract() content = \'\'.join(content) dic = { "title": title, "content": content } all_data.append(dic) return all_data # 终端指令 # scrapy crawl spiderName -o duanzi.csv 基于管道的持久化存储 scrapy建议使用管道持久化存储
实现流程
数据解析(spiderName .py)
实例化item类型对象(items.py)
在items.py的item类中定义相关的属性
fieldNmae = scrapy.Field()
将解析的数据存储封装到item类型的对象中(spiderName .py)
item[\'fileName\'] = value 给item对象的fieldNmae属性赋值
将item对象提交给(spiderName .py)
yield item 将item提交给优先级最高的管道
在管道中接收item,可以将item中存储的数据进行任意形式的持久化存储(pipelines.py)
process_item():负责接收item对象且对其进行持久化存储
在配置文件settings.py中开启管道机制
找到如下代码,取消注释
ITEM_PIPELINES = { # 300表示的是优先级,数值越小,优先级越高 \'duanziPro.pipelines.DuanziproPipeline\': 300, }案例:将文本数据持久化存储
按上述在settings.py找到管道代码,取消注释。