爬虫框架(scrapy架构)

1.scrapy架构流程:
在这里插入图片描述

scrapy主要包括了以下组件:
1.)引擎(scrapy):用来处理整个系统的数据流,触发事务(框架核心)
2.)调度器(Scheduler):用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回,可以想象成一个url(抓取网页的网址或者说链接)的优先队列,由它来决定下一个要抓取的网址是什么,同时去除重复的网址。
3.)下载器(Downloader):用于下载网页的内容,并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
4.)爬虫(Spiders):爬虫是主要干活的,用于从特定的网页中提取自己想要的信息,即所谓的实体(item)。用户也可以从中提取到链接,让Scrapy继续抓取下一个页面。
5.)项目管道(Pipeline):负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
(只有当调度器中不存在任何request时,整个程序才会停止。(对于下载失败的url,Scrapy也会重新下载))

前置要求:
pip下载scrapy模块
yum下载tree包

爬取的步骤

-确定url地址;
-获取页面信息;(urllib,requests)
-解析页面提取需要的信息;(xpath,bs4,正则表达时)
-保存到本地(scv,json,pymysql,redis)
-清洗数据(删除不必要的内容------正则表达式)
-分析数据(词云wordcloud,jieba)

流程分析

-确定url地址(spider)
-获取页面信息(Downloader)
-解析页面提取需要的信息(spider)
-保存到本地(pipeline)

环境

scrapy1.6.0

实现步骤

1.工程创建
1.)命令行在当前目录下创建mySpider

scrapy startproject mySpider

2.)创建成功后,进入mySpider ,tree查看

cd mySpider
tree

在这里插入图片描述
2.创建一个爬虫

#scrapy genspider 项目名 url
scrapy genspider mooc ‘www.imooc.com

3.定义爬取的items内容(items.py)

class CourseItem(scrapy.Item):

#课程标题
title=scrapy.Field()
#课程的url地址
url=scrapy.Field()
#课程图片的url地址
image_url=scrapy.Field()
#课程的描述
introduction=scrapy.Field()
#学习人数
student=scrapy.Field()

4.编写spider代码,解析
4.1确定url地址,提取页面需要的信息(mooc.py

class MoocSpider(scrapy,spider):

#name用于区别爬虫,必须唯一
name=‘mooc’
#允许爬取的域名,其他网站的页面直接跳过
allowd_domains=[‘www.imooc.com’,‘img3.mukewang.com’]
#爬虫开启时第一个放入调度器的url地址
start_urls=[‘http://www.imooc.com/course/list’]
#被调用时,每个新的url完成下载后,返回一个响应对象
#下面的方法负责将响应的数据分析,提取出需要的数据items以及生成下一步需要处理的url地址请求;
def parser(self,response):

##用来检测代码是否达到指定位置,并用来调试并解析页面信息;
#from scrapy.shell import inspect_response
#inspect_response(response,self)
#1.)实例化对象,CourseItem
course=CourseItem()
#分析响应的内容
#scrapy分析页面使用的是xpath方法
#2.)获取每个课程的信息
courseDetails=course.xpath(’.//div[@class=“course-card-container”]’)
for courseDetail in courseDetails:

#爬取新的网站, Scrapy里面进行调试(parse命令logging)
course[‘title’] = courseDetail.xpath(’.//h3[@class=“course-card-name”]/text()’).extract()[0]
#学习人数
course[‘student’] = courseDetail.xpath(’.//span/text()’).extract()[1]
#课程描述:
course[‘introduction’] = courseDetail.xpath(".//p[@class=‘course-card-desc’]/text()").extract()[0]
#课程链接, h获取/learn/9 ====》 http://www.imooc.com/learn/9
course[‘url’] = “http://www.imooc.com” + courseDetail.xpath(’.//a/@href’).extract()[0]
#课程的图片url:
course[‘image_url’] = ‘http:’ + courseDetail.xpath(’.//img/@src’).extract()[0]
yield course
#url跟进,获取下一步是否有链接;href
url=response.xpath(’.//a[contains[text(),“下一页”]/@href’)[0].extract()
if url:

#构建新的url
page=‘http://www.imooc.com’+url
yield scrapy.Request(page,callback=slef.parse)

4.2保存我们提取的信息(文件格式:scv,json,pymysql)(pipeline.py
如果多线程,记得在settings.py中分配多个管道并设置优先级:
在这里插入图片描述
(1).将爬取的信息保存成json格式

class MyspiderPipeline(object):

def init(self):

self.f=open(Moocfilename,‘w’) #Moocfilename是写在settings.py里的文件名,写在setting.py是因为方便修改

def process_item(self,item,spider):

#默认传过来的格式是json格式
import json
#读取item中的数据,并转化为json格式
line=json.dumps(dict(item),ensure_ascii=False,indent=4)
self.f.write(line+’\n’)
#一定要返回给调度器
return item

def close_spider(self,spider):

self.f.close()

(2).保存为scv格式

class CsvPipeline(object):

def init(self):

self.f=open(’'mooc.csv",‘w’)

def process_item(self,item,spider):

item=dict(item)
self.f.write("{0}:{1}:{2}\n".format(item[‘title’] , item[‘student’] , item[‘url’]))
return item

def close_spider(self,spider):

self.f.close()

(3).将爬取的信息保存到数据库中
首先打开数据库创建mooc表

class MysqlPipeline(object):

def init(self):

self.conn=pymysql.connect(
host=‘localhost’,
user=‘root’,
password=‘redhat’,
db=‘Mooc’,
charset=‘utf8’,
)
self.cursor=self.conn.cursor()

def process_item(self,item,spider):

item=dict(item)
info=(item[’‘item"] , item[“url”] , item[“image_url”] , item[“introduction”] , item[“student”])
insert_sqil="insert into moocinfo values(’%s’ , ‘%s’ , ‘%s’, ‘%s’ , ‘%s’); " %(info)
self.cursor.execute(insert_sqil)
self.conn.commit()
return item

def open_spider(self,spider):

create_sqli=“create table if not exists moocinfo (title varchar(50),url varchar(200), image_url varchar(200), introduction varchar(500), student int)”
self.cursor.execute(create_sqli)

def close_spider(self,spider):

self.cursor.close()
self.conn.close()

(4).通过爬取的图片链接下载图片

class ImagePipeline(object):
	def get_media_requests(self,item,info):
	#返回一个request请求,包含图片的url
	yield scrapy.Request(item['image_url'])
def item_conpleted(self,results,item,info):
	#获取下载的地址
	image_xpath=[x['path'] for ok , x in results if ok]
	if not image_path:
		raise Exception('不包含图片')
	else:
		return item

scrapy反爬虫策略

1.策略一:设置download_delay
–作用:设置下载的等待时间,大规模集中的访问对服务器的影响最大,相当于短时间内增大服务器的负载
–缺点:下载等待时间长,不能满足段时间大规模抓取的要求,太短则大大增加了被ban的几率

2.策略二:禁止cookies
–cookie有时也用作复数形式cookies,指某些网站为了辨别用户的身份,进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
–作用:禁止cookies也就防止了可能使用cookies识别爬虫轨迹的网站得逞
–实现:COOKIES_ENABLES=False

3.策略三:使用user_agent池(拓展:用户代理中间件)
–为什么要使用?scrapy本身是使用Scrapy/0.22.2来表明自己的身份。这也就暴露了自己是爬虫的信息。
–user agent ,是指包含浏览器信息,操作系统信息等的一个字符串,也称之为一种特殊的网络协议。服务器通过它判断当前的访问对象是浏览器,邮件客户端还是爬虫。

4.策略四:使用代理中间件
–web server应对爬虫的策略之一就是直接将你的ip或者是整个ip段都封掉禁止访问,这时候,当ip封掉后,转换到其他的ip继续访问即可。

5.策略五:分布式爬虫Scrapy+redis+mysql # 多进程
–Scrapy-Redis则是一个基于Redis的Scrapy分布式组件。它利用Redis对用于爬取的请求(Requests)进行存储和调度(Schedule),并对爬取产生rapy一些比较关键的代码,将Scrapy变成一个可以在多个主机上同时运行的分布式爬虫。

猜你喜欢

转载自blog.csdn.net/qq_37037438/article/details/87800036