之前的工作都是針對網(wǎng)頁內(nèi)容,進(jìn)行xpath解析之后整理入庫颅夺,
或者寫入csv朋截、doc之類,
然后突然收到要去某個(gè)網(wǎng)站搜索含“附件”關(guān)鍵詞的文章吧黄,
并將其中的附件下載部服,沒有下載標(biāo)簽的則保存內(nèi)容存為doc。
首先想到的是使用Scrapyd框架的下載器-官方文檔
使用方法也很簡單拗慨,如果不需要對文件進(jìn)行特殊處理只需要
settings.py
# 在配置文件的ITEM_PIPELINES模塊加上這一句廓八,啟用FilesPipeline
ITEM_PIPELINES = {
'scrapy.pipelines.files.FilesPipeline': 1,
'myproject.pipelines.MyFilePipelines': 1, # 自定義pipelines規(guī)則
}
# 配置文件存放目錄
FILES_STORE = '/pth/to/file/dir'
-------------------------------------------------------------------------------------------
item.py
# 類似于入庫操作,設(shè)置ITEM胆描,但必須包含file_urls和files
class MyFilesItem(scrapy.Item):
files = scrapy.Filed()
file_urls = scrapy.Field()
file_name = scrapy.Field() #如果需要自定義文件名
pass
-------------------------------------------------------------------------------------------
pipelines.py
# 需要自定義pipeline規(guī)則時(shí)使用,使用默認(rèn)配置不需要更改,自己的項(xiàng)目文檔....懶的改
class MyFilePipeline(FilesPipeline):
def file_path(self, request, response=None, info=None):
# 對文件重命名時(shí)需要重寫的方法, Return file path
item = request.meta['item']
dic_file_type = {'tzgg': u'通知公告', 'xmsyj': u'畜牧獸醫(yī)局', 'nyjstgzz': u'農(nóng)業(yè)技術(shù)推廣總站',
'ncjjtzyjyglc': u'農(nóng)村經(jīng)濟(jì)體制與經(jīng)營管理處', 'szzglzz': u'種子管理總站', 'ncjjzzglc': '農(nóng)產(chǎn)品加工辦公室',
'ncpzlaqjgc': u'農(nóng)產(chǎn)品質(zhì)量安全監(jiān)管局', 'kjjyc': u'科技教育處', 'zzyglc': u'種植業(yè)管理處',
'nyyw': u'農(nóng)業(yè)要聞'}
file_type = dic_file_type[(request.url.split('/')[4])]
file_name = item['file_name']
file_path_name = u'full/{0}/{1}'.format(file_type, file_name)
# file_dir = u'full/{0}'.format(file_type)
# is_file_path = ''.join(['D:/work/studyscrapy/', file_path_name])
# if not os.path.exists(is_file_path):
# os.makedirs(file_dir)
return file_path_name
def get_media_requests(self, item, info):
# FilesPepeline 根據(jù)file_urls指定的url進(jìn)行爬取瘫想,該方法為每個(gè)url生成一個(gè)Request后 Return
for file_url in item['file_urls']:
yield Request(file_url, meta={'item': item})
def item_completed(self, results, item, info):
# 所有圖片處理完畢后會調(diào)用該方法,也可以在該方法下進(jìn)行文件重命名
file_paths = [x['path'] for ok, x in results if ok]
if not file_paths:
# 如果文件未下載
raise DropItem("Item contains no file")
item['file_paths'] = file_paths
return item
-----------------------------------------------------------------------------------------
spider.py
# 局部代碼示例,僅作說明item使用方法
class mySpider(scrapy.Spider):
# 初始化全局變量
file_urls = []
def parse(response):
sel = Selector(response)
item = myFileItem()
a = sel.xpath('//a[@class="ul_list li"]')
if len(a) != 0:
for f in a:
self.file_type.append(meta['type'])
self.file.append(f.xpath('.//text()').extract_first(default='N/A'))
f_url = f.xpath('.//@href').extract()[0]
f_name = f.xpath('.//text()').extract()[0]
if f_url[0] == '.':
f_site = response.url.split('/')
f_site[-1] = f_url[2::]
f_url = '/'.join(f_site)
item['files'] = f_name
item['file_urls'] = [f_url]
item['file_name'] = f_name
yield item
如果不寫自己的filepipeline,文件名是使用file_url的SHA1 hash昌讲,不利于文章的分類整理国夜。
還沒有試過imagepipeline,不過具體用法類似短绸,用上了再看