简介
scrapy [skreɪp] 是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量代码,就能够快速的抓取到数据内容。Scrapy 使用了 Twisted (其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。['twɪstɪd]
所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。
安装
- Linux:
pip3 install scrapy
- Windows:
a. pip3 install wheel
b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl
d. pip3 install pywin32
e. pip3 install scrapy
基础使用
1. 创建项目
scrapy startproject 项目名称
2. 创建爬虫应用程序
1) cd projectName (进入到项目目录)
2) scrapy genspider 应用名称 爬虫网页的起始url spider: ['spaɪdə]
如: scrapy genspider qiubai www.qiushibaike.com
3. 编写爬虫文件:步骤2执行完后,会在项目的spiders中生成一个应用名的py爬虫文件
4. 执行爬虫程序
scrapy crawl 应用名称 [krɔl]
5. 基于终端指令的持久化存储
保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作。
scrapy crawl first -o 爬虫名称.csv # 保存为以 .csv后缀名的文件
6. log日志
scrapy crawl 爬虫名称 :该种执行形式会显示执行的日志信息
scrapy crawl 爬虫名称 --nolog:该种执行形式不会显示执行的日志信息
extract: [ɪk'strækt]
目录结构
└── project_name/
├── scrapy.cfg: # 项目的主配置信息。(真正爬虫相关的配置信息在settings.py文件中)
├── project_name/
│ └── __init__.py
│ │
│ ├── items.py # 设置数据存储模板,用于结构化数据,如:Django的Model
│ │
│ ├── pipelines.py # 数据持久化处理
│ │
│ ├── settings.py # 配置文件,如:递归的层数、并发数,延迟下载等
│ │
└── ├── spiders/ # 爬虫目录,如:创建文件,编写爬虫解析规则
└── __init__.py
爬虫文件
# -*- coding: utf-8 -*-
import scrapy
class QiubaiSpider(scrapy.Spider):
# 爬虫文件的名称:就是爬虫文件的一个唯一标示
name = 'qiubai'
# 允许爬取的域名(如果遇到非该域名的url则爬取不到数据)一般注释
allowed_domains = ['https://www.qiushibaike.com/']
# 起始爬取的url列表: 列表元素都会被自动的进行请求的发送
start_urls = ['https://www.qiushibaike.com/', 'www.baidu.com']
# 访问起始URL并获取结果后的回调函数,该函数的response参数就是向起始的url发送请求后,获取的响应对象.该函数返回值必须为可迭代对象或者NUll
def parse(self, response):
print(response.text) # 获取字符串类型的响应内容
print(response.body) # 获取字节类型的相应内容
settings.py 配置文件
1. 伪装请求载体身份标识
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
2. 可以忽略或者不遵守robots.txt协议
ROBOTSTXT_OBEY = False
3. 日志等级
LOG_LEVEL = '指定日志信息种类' # 显示的日志等级
LOG_FILE = 'log.txt' # 则表示将日志信息写入到指定文件中进行存储。
日志信息的种类:
- ERROR # 一般错误
- WARNING # 警告
- INFO # 一般信息
- DEBUG # 调试信息
4. 修改scrapy的并发线程, 默认为32个
CONCURRENT_REQUESTS = 100
5. 禁止cookie, scrapy默认处理cookie值
COOKIES_ENABLED = False
6. 禁止重试:对失败的HTTP进行重新请求(重试)会减慢爬取速度,可以禁止重试。
RETRY_ENABLED = False
7. 减少下载超时: 如果对一个非常慢的链接进行爬取,减少下载超时能让卡住的链接快速被放弃,来提升效率。
DOWNLOAD_TIMEOUT = 10
示例
爬取糗图百科
# -*- coding: utf-8 -*-
import scrapy
class QiubaiSpider(scrapy.Spider):
name = 'qiubai'
allowed_domains = ['https://www.qiushibaike.com/']
start_urls = ['https://www.qiushibaike.com/']
def parse(self, response):
# xpath为response中的方法,可以将xpath表达式直接作用于该函数中
odiv = response.xpath('//div[@id="content-left"]/div')
content_list = [] # 用于存储解析到的数据
# 特性:xpath返回的列表元素个是Selector对象,使用extract()来获取Selector中data的数据
for div in odiv:
author = div.xpath('.//div[@class="author"]/a/h2/text()')[0].extract()
content=div.xpath('.//div[@class="content"]/span/text()')[0].extract()
# 第二种写法
# author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
# 基于终端指令进行持久化存储的时候必须将解析到的数据封装到字典中
dic={
'作者':author,
'内容':content
}
# 将数据存储到content_list这个列表中
content_list.append(dic)
return content_list