同步异步
异步:调用在发出之后,这个调用就直接返回,不管有无结果
非阻塞:关注的是程序在等待调用结果 (消息,返回值)时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程
scrapy的安装与使用
windows安装方式
pip3 install ipgrade pip
通过pip安装Scrapy框架
pip3 install Scrapy
Ubuntu 安装方式
sudo pip3 install scrapy
如果安装不成功再试着添加这些依赖库:
安装非Python的依赖
sudo apt-get install python3-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev
新建项目
scrapy startproject 爬虫项目名称
新建爬虫文件
scrapy genspider jobbole jobbole.com
启动
scrapy crawl +项目名称
根据目标网站分析需要提取的数据,在item.py文件中添加字段
打开jobboleproject文件下的item.py文件
item 定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但是提供了一些额外的保护减少错误。
可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field的类属性来定义一个Item(可以理解成类似于ORM的映射关系)
制作爬虫
要建立一个Spider, 你必须用scrapy.Spider类创建一个子类,并确定了三个强制的属性 和 一个方法。
name = “” :这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
allow_domains = [] 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
start_urls = () :爬取的URL元祖/列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
parse(self, response) :解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,
主要作用如下:
负责解析返回的网页数据(response.body),提取结构化数据(生成item)
生成需要下一页的URL请求。
将start_urls(设置起始url)的值修改为需要爬取的第一个url
yelid函数
yield 的作用就是把一个函数变成一个 generator(生成器),带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,带有yeild的函数遇到yeild的时候就返回一个迭代值,下次迭代时,代码从 yield 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,
直到再次遇到 yield。
通俗的讲就是:在一个函数中,程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行,如此循环,直到函数执行完。
Scrapy Item pipeline(管道文件)使用
Item Pipeline
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item。
每个Item Pipeline都是实现了简单方法的Python类,比如决定此Item是丢弃而存储。以下是item pipeline的一些典型应用:
验证爬取的数据(检查item包含某些字段,比如说name字段)
查重(并丢弃)
将爬取结果保存到文件或者数据库中
数据持久化
方式一:数据存入mongodb数据库
settings.py文件:
设置文件,在这里设置User-Agent,激活管道文件等
ITEM_PIPELINES = {
'douban.pipelines.DoubanPipeline': 300,
}
MONGODB_HOST = '127.0.0.1' #MONGODB 主机名
MONGODB_PORT= 27017 #MONGODB 端口号
MONGODB_DBNAME = "Douban" #数据库名称
MONGODB_SHEETNAME= "doubanmovies" #存储数据的表名称
在管道pipelines.py中进行数据持久化
import pymongo from scrapy.conf import settings
class DoubanPipeline(object):
# 将数据存储在mongodb中
def __init__(self,host,port,dbname,sheetname):
# 创建MONGODB数据库链接
client = pymongo.MongoClient(host=host, port=port)
# 指定数据库
mydb = client[dbname]
# 存放数据的集合名称
self.mysheet = mydb[sheetname]
@classme