一:文件下载的配置文件:
setting.py文件配置选项
文件下载保存路径(重写了FilesPipeline默认输出路径:file_dir)
FILES_STORE = 'download'
ITEM_PIPELINES = {
文件的FilesPipeline必须设置为1,最先执行!
'scrapy_first.pipelines.MyFilesPipeline': 1,
}
二、重写 FilesPipeline类,自定义输出文件名
class MyFilesPipeline(FilesPipeline):
此方法FilesPipeline和ImagesPipeline内部已经执行,可以省略不重写
# def get_media_requests(self, item, info):
# for file_url in item['file_urls']:
# yield Request(file_url)
此方法FilesPipeline和ImagesPipeline内部已经执行,可以省略不重写
# def item_completed(self, results, item, info):
# file_paths = [x['path'] for ok, x in results if ok]
# if not file_paths:
# raise DropItem("Item contains no files")
# item['file_paths'] = file_paths
# return item
如果要选择自己的文件名输出格式,必须重写FilesPipeline类的file_path方法
def file_path(self, request, response=None, info=None):
'''自定义图片保存路径,以图片的url保存,重写前是图片的url经过MD5编码后存储'''
file_path = "".join(re.findall("https://matplotlib.org/([\w\W]+)",request.url))
return f'file_dir/{file_path}'
三、写爬虫获取要下载的文件链接(务必注意,js、css这些动态加载的链接必须从process_value函数中截获
from scrapy import Spider
from scrapy.linkextractors import LinkExtractor
import re
from ..items import DownloadItem
class DownloadSpider(Spider):
name = "download"
allowed_domains = ["matplotlib.org"]
start_urls = ["https://matplotlib.org/gallery/index.html"]
def __init__(self, name=None, **kwargs):
super().__init__(name=name, **kwargs)
self.links =[]
def parse(self, response):
ext = LinkExtractor(tags=["link","script"],attrs=["src","href"],process_value=self.process_value)
# js、css链接会extract_links过滤掉,所以在process_value方法截获保存到self.links列表
ext.extract_links(response)
# FilesPipeliney已经实现了file_urls字段
item = DownloadItem()
if self.links:
# file_urls字段是文件下载官方代码规定的(传入FilesPipeline需要)
item["file_urls"] = self.links
# 这些链接是传入FilesPipeline下载,所以直接生成数据即可!
yield item
# extract_links方法获取的所有连接都会调用此函数
def process_value(self,value):
if self.value_not_reg(value):
# 在这里截获所有的链接,帅选出css和js等文件保存起来
self.links.append(value)
return value
# 正则表达式过掉的不是js或css文件的链接
def value_not_reg(self,value):
return re.fullmatch("[\w\W]+?\.css$",value) or re.fullmatch("[\w\W]+?\.js$",value)
class DownloadItem(Item):
file_urls = Field()