概述
settings.py设置
#是否遵守robot协议,遵守协议后只能爬取网站允许爬取的数据
ROBOTSTXT_OBEY = True
#管道设置
ITEM_PIPELINES = {
项目名.pipelines.管道名=参数
}
#参数值:0~1000,数值越小优先级越高
管道文件:pipelines.py
#初始化方法,可选方法
def __init__(self):
#处理item数据的方法,必须实现方法
def process_item(self, item, spider):
#一定要return item,告诉调度器处理完item了,不然程序在这里中断
return item
#sipder开启时调用的方法,可选方法
def open_spider(self, spider):
#sipder结束时调用的方法,可选方法
def close_spider(self, spider):
#sipder:爬虫对象
setting.py文件中启用的管道文件都会执行,只是根据管道的参数,优先级不同。
管道文件作用:
- 验证爬取的数据:item[属性],可以查看item某个属性的值
- 查重:python查重方法:set集合
- 爬取结果保存(文件、数据库)
spider:爬虫程序
作用:爬虫程序的主要实现,发送请求,解析网页等操作
所有的代码都写在类中,类名是爬虫程序名+Spider
,类继承scrapy.Spider
,所以要导入scrapy库。
需要写的属性:
name = "爬虫程序名"
allowed_domains = ["网址:限制爬虫的爬取范围,在指定的网址内"]
start_urls = ["链接:初始的爬虫的连接,程序运行之后,第一爬的连接"]
必须的方法:
def parse(self, response):
self:调用类中的属性,让每个方法中调用变量不受限制
response:接受上一个函数发送过来的response,可以直接通过xpath解析
方法最后,使用yield
关键字,通过scrapy.Request()
方法请求下一个链接,并将请求返回的response发送给指定的回调函数,如果不指定回调函数,则默认回调给parse
方法。
yield scrapy.Request(url,callback=self.parse_two,headers=self.headers,dont_filter=True,meta={"type1":name_list[node]})
meta
参数用来传输数据,可以把变量传递给指定的回调函数。下一个函数解析时,通过response解析。
type1 = response.meta['type1']
爬虫程序结束后,最后一个函数将封装好的item
发送给管道。
yield item
item:实体类
作用:封装数据,在爬虫程序与管道之间传送数据。
类似于java中的实体类。只不过省略的get与set方法,每个变量都是通过scrapy.Field()
赋值。
需要继承scrapy.Item
类
默认有一个爬虫程序名+Item
组成的类。
middleware:中间件
可以在请求发送之前和请求返回之后,对数据进行处理。
可以将一个类理解成一个中间件操作。
请求发送前:
修改请求头,使用代理IP等操作。
修改请求头:
fake_useragent:随机请求头的python库。
from fake_useragent import UserAgent
class RandomUserAgentMiddleware(object):
def process_request(self, request, spider):
ua = UserAgent()
yield request.headers['User-Agent'] = ua.random
每次scrapy发送请请求之前都会调用这个中间件,修改请求头参数。
pipeline:管道
作用:处理爬下来的数据。
一个文件中可以定义多个管道,每一个管道就是一个类。
普通管道:
可以不用继承类,或者继承object类。
process_item(self,item,spider)
方法:必须实现的方法,接收爬虫发送过来的item,处理这些item,最后必须要return item
或yield item
,否则爬虫程序不会继续执行。
选用的方法:
- open_spider(self, spider):在爬虫程序启动时就执行的方法。可以用来连接数据库等操作。
- close_spider(self,spider):在爬虫程序执行结束后执行的方法。
下载管道:
scrapy提供了用来下载文件和图片的管道。需要使用时实现。
下载文件:
定义下载文件的管道类,继承FilesPipeline
类。同理如果下载图片,继承ImagesPipeline
类
需要重写的方法:get_media_requests,发送请求item中封装的文件链接,下载完成时调用item_completed(self, results, item, info):
方法,reults
中包括多个参数,其中就有下载的成功与否的参数。
file_path
方法,将文件名重命名成爬虫爬下来的文件名。
# 下载文件
class SogouWordFilePipeline(FilesPipeline):
def get_media_requests(self, item, info):
yield scrapy.Request(item['dictUrl'], meta={'item': item})
# 下载完成时调用
def item_completed(self, results, item, info):
file_paths = [x['path'] for ok, x in results if ok]
if not file_paths:
print('下载失败')
raise DropItem("Item contains no files")
print(item['dictName']+'下载成功')
return item
# 文件名
def file_path(self, request, response=None, info=None):
item = request.meta['item']
path = item['dictName']
return path
setting:爬虫项目设置
ROBOTSTXT_OBEY = False #设置是否遵守ROBOTSTXT协议,遵守的话有的数据爬不下来
DOWNLOAD_DELAY = random.uniform(0,1) # 请求时间间隔
COOKIES_ENABLED = False # 是否启用cookies,一般禁用,用的网站会根据cookies来反爬虫
# 中间件配置,启用哪些中间件,启用的中间件在当前项目中的所有爬虫程序都生效,根据数值执行,数值越小的优先级越高
DOWNLOADER_MIDDLEWARES = {
# 'sougou.middlewares.SougouDownloaderMiddleware': 543,
'sougou.middlewares.RandomUserAgentMiddleware': 543,
# 'sougou.middlewares.SougouRandomProxyMiddleware': 543,
}
# 管道配置,启用哪些管道,同样,在当前项目中的所有爬虫程序都生效,数值越小,优先级越高
ITEM_PIPELINES = {
'sougou.pipelines.SogouWordFilePipeline': 2,
# 'sougou.pipelines.SougouPipeline': 300,
}
# 如果启用下载文件的中间件,需要设置此项,设置下载的文件保存到哪个目录
FILES_STORE = 'dict_list' # 文件目录
IMAGES_STORE= "" # 图片目录