开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
今天介绍一个爬虫中的框架scrapy,这个框架可以实现分布式爬虫。
1.什么是分布式爬虫?
我们熟知的爬虫分类有通用爬虫,聚焦爬虫,分布式爬虫这三种。那么基于scrapy框架实现的分布式爬虫有什么优点呢?
(1)Scrapy 使用了Twisted异步网络框架,可以加快我们的下载速度。
(2)Scrapy可以实现少量的代码快速的抓取数据
(3)Scrapy可以大大提高抓取的效率
2.scrapy框架的工作流程
调度器把requests-->引擎-->下载中间件--->下载器 下载器发送请求,获取响应---->下载中间件---->引擎--->爬虫中间件--->爬虫 爬虫提取url地址,组装成request对象---->爬虫中间件--->引擎--->调度器 爬虫提取数据--->引擎--->管道 管道进行数据的处理和保存
3.scrapy的使用
(1)创建一个scrapy项目:scrapy startproject mySpider
(2)生成一个爬虫:scrapy genspider Sixstar "sixstaredu.com
(3)提取数据:完善spider,使用xpath等方法
(4)保存数据:pipeline中保存数据
- scrapy创建项目 安装scrapy命令:sudo apt-get install scrapy 或者:pip install scrapy
创建scrapy项目的命令:scrapy startproject +<项目名字>
示例:scrapy startproject douban
在项目路径下执行:scrapy genspider +<爬虫名字> + <允许爬取的域名>
注意:这里执行这个命令之前一定要确保是在项目的路径下执行,项目的路径下执行的意思就是将整个豆瓣的项目文件单独一个窗口打开,之前的文章中有提到过可以去看看
下面示例创建一个:
cd douban
scrapy genspider xxx douban.com
5.举例
下面举例使用crapy框架抓取豆瓣网站的数据,spider的部分主要实现抓取的逻辑,大部分的代码编写都在这里:
import scrapy
class DoubanTestSpider(scrapy.Spider):
name = 'douban_test'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250?start=%s&filter='%i for i in range(0,226,25)]
def parse(self, response):
urls = response.xpath('//*[@id="content"]/div/div[1]/ol/li[*]/div/div[1]/a/@href').getall()
# 获取所有详情页的url
for url in urls:
item = {}
yield scrapy.Request(url,callback=self.parse_detail,meta={'item':item})
def parse_detail(self,response):
title_ = response.xpath('//*[@id="content"]/h1/span[1]/text()').get()
score_ = response.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/strong//text()').get()
time_ = response.xpath('//div[@class="subjectwrap clearfix"]/div/div/span[@property="v:runtime"]/@content').get()
type_ = response.xpath('//div[@class="subject clearfix"]/div/span[@property="v:genre"][1]/text()').getall()
num_ = response.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/div/div[2]/a/span/text()').get()
propotion_ = response.xpath('//*[@id="interest_sectl"]/div[1]/div[3]/div[1]/span[2]/text()').get()
item = response.meta.get('item')
item['title'] = title_
item['score'] = score_
item['time'] = time_
item['type'] = ''.join(type_)
item['num'] = num_
item['propotion'] = propotion_
yield item
设置管道的保存逻辑,用于数据的保存,这里是连接了本地的mysql数据库,将数据保存在本地的mysql数据库中,后期对数据调用直接使用命令就可以实现数据的操作,以下是保存逻辑的实现
from itemadapter import ItemAdapter
import pymysql
class DoubanPipeline:
def process_item(self, item, spider):
conn = pymysql.connect(user='root',password='*****',
charset='utf8',database='douban')
cur = conn.cursor()
cur.execute('insert into films value("%s","%s","%s","%s","%s","%s")'%
(item['title'],item['score'],item['time'],item['type'],item['num'],item['propotion']))
conn.commit()
cur.close()
conn.close()
return item
以上的代码从基本的项目创建、域名的设置以及使用命令运行一个爬虫程序最后就以你豆瓣网为例创建一个scrapy项目,然后基于scrapy框架对数据抓取。 在后面的文章中会分享一些管道的开启,请求头的设置以及一些scrapy使用的注意点。