什么是Scrapy框架?
Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途非常广泛。多用于抓取大量静态页面。
框架的力量: 用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。
Scrapy 使用了 Twisted['twɪstɪd] (其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。
怎样安装Scrapy?
pip install scrapy
Scrapy运行流程
Scrapy构架解析:
Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。
Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
Downloader Middlewares:(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
本次目标
创建项目
scrapy startproject my(项目名称) #相对路径下创建项目名称
创建文件
cd myspider(项目名称目录) #cd到目录
scrapy genspider My(文件名称,不能跟项目名一样) baidu.com(要访问的url) #当前目录创建文件
主要文件作用
文件结构一览
1、明确爬虫要抓取的目标,编写items.py字段,用来存储返回值的容器。
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class DoubanItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
titles = scrapy.Field() #爬取的目标字段需要定义到这里,用来保存数据,否则后面爬取的数据无法保存
urls = scrapy.Field()
2、制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页。这里负责写目标爬虫的规则,获取到目标数据,返回到
# -*- coding: utf-8 -*-
import scrapy
from ..items import MyItem #导入items,才能把得到的目标数据返回到items中
class MySpider(scrapy.Spider):
name = 'My' #项目文件名称
allowed_domains = ['baidu.com'] #项目域名定位,约束到这个范围内
start_urls = ['http://baidu.com/'] #爬虫的入口url
items = MyItem() #先实例化item,然后得到目标数据后用yield返回出去
## item['title'] = xxx(得到的数据),
## 字段必须items.py里面先定义(注意这个是在得到数据的地方返回出去)
## 返回用 yield items
def parse(self, response): #这里开始写请求入口url后的操作,这里获取到的数据会保存到之前items里面创建的对应的字段里面。最后传递给pipeline.py,看下面进行存储???????
pass
yield scrapy.Request(url,callback=self.index) #生成跟进url,再次进行处理。
def index(self): #处理跟进的请求
pass
3、存储内容 (pipelines.py):设计管道存储数据,(mySpider/settings.py里面的注册管道,默认是禁用的 )
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
class MyPipeline(object):
def process_item(self, item, spider): #返回的是定义字段规则的目标数据item,这里可以写对数据的处理及存储操作。
return item
注意:这是在命令模式下操作,不是python环境中!
1、创建项目
scrapy startproject ndouban #创建一个ndouban项目
2、创建模块文件
cd ndouban #cd 到项目文件目录里面
scrapy genspider douban movie.douban.com/chart #然后创建模块文件,指定文件名及域名
3、开始编写爬虫文件
编写目标items.py字段
import scrapy
class NdoubanItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() #定义 豆瓣电影名,这边定义另一边返回值才有地方存,不然报错
url = scrapy.Field() #定义 电影的url
编写爬虫的spider文件,获取目标数据
# -*- coding: utf-8 -*-
import scrapy
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com/chart'] #目标域名
start_urls = ['https://movie.douban.com/chart/'] #默认生成的url有问题,自行更改目标url
def parse(self, response):
target = response.xpath('//div[@class="pl2"]/a') #获取到目标节点nodename
title = target.xpath('string()').extract() #加extract()才能转为字符,结果返回的是列表
url = target.xpath('@href').extract()
#print(title,url)
for i in zip(title,url): #对列表做一些处理,方便查看
print(i)
运行可以查看效果
运行前需要进行一些设置(settings.py里面)
默认scrapy框架是遵循网站权限的,不给爬虫权限的不会访问,把权限改为False即可访问
ROBOTSTXT_OBEY = False #默认是True,改为False
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'} #有些网站会验证请求头,这里可以定义一个。
ITEM_PIPELINES = {
'ndouban.pipelines.NdoubanPipeline': 300,
} #这个是最后的结果返回给piplines以做存储的,默认是注释掉的,可以先解开。
运行·
scrapy list #可以查看项目名
scrapy crawl douban #执行douban这个项目
部分截图,具体自己测试了解
4、数据已经爬取下来了,下面传递给items
# -*- coding: utf-8 -*-
import scrapy
from ..items import NdoubanItem #导入item模块
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com/chart'] #目标域名
start_urls = ['https://movie.douban.com/chart/'] #默认生成的url有问题,自行更改目标url
def parse(self, response):
items = NdoubanItem() # 实例化item对象???????????
target = response.xpath('//div[@class="pl2"]/a') #获取到目标节点nodename
title = target.xpath('string()').extract() #加extract()才能转为字符,结果返回的是列表
url = target.xpath('@href').extract()
for x,y in zip(title,url):
items['title'] = x
items['url'] = y
yield items #传递给items.py???????????
item字段接收返回值
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NdoubanItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 定义 豆瓣电影名
url = scrapy.Field() # 定义 电影的url
print(title)
print(url) #为了预览效果,在这里可以打印出来,看程序是否传值过来
结果部分预览
*可以发现是字典key形式
5、items获取到数据时,pipelines.py模块中也获取到了数据,item就是数据打包的,需要存储就在这写方法
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
class NdoubanPipeline(object):
def __init__(self):
self.f = open('yy.json',mode='w',encoding='utf8') #先生成一个文件,方便后面写入数据
def process_item(self, item, spider): #返回的item是一个class的对象,转成dict.
tt = json.dumps(dict(item),ensure_ascii=False) #linux默认不显示中文,加入这个方法
self.f.write(tt)
return item
仅供参考,作为学习笔记方便后面查阅,理解错误的地方请无视我哈哈哈?