Python 爬虫案例(二)

此篇文章将爬取的网站是:http://www.warrensburg-mo.com/Bids.aspx (有时候打开不一定会有标书,因为标书实时更新) 类型跟上一篇相似,用google浏览器,但在这篇中会讲如何下载附件,Scrapy框架中提供了FilesPipeline专门用于下载文件。另外以后发布的爬虫博客也会循序渐进:
爬取目标:下载附件,自己命名附件名称,解决下载链接的重定向问题
我们还是在csdn项目中操作(案例一中有创建过),小编比较懒:

首先在 items.py 中添加几项,因为我们这次多了download的步骤:

import scrapy
class CsdnItem(scrapy.Item):title = scrapy.Field()expiredate = scrapy.Field()issuedate = scrapy.Field()web_url = scrapy.Field()bid_url = scrapy.Field()  #这5个在上一篇讲过了  file_urls = scrapy.Field() # 附件链接

接下来我们在左侧栏的spiders文件下面创建一个Python File,取名为warrensburg,系统会自动生成一个warrensburg.py的爬虫文件:

import scrapy
import datetime
from scrapy.http import Request
from CSDN.items import CsdnItemclass WarrensburgSpider(scrapy.Spider):name = 'warrensburg'start_urls = ['http://www.warrensburg-mo.com/Bids.aspx']domain = 'http://www.warrensburg-mo.com/'def parse(self, response):#xpath定位找出bid所在的区域result_list = response.xpath("//*[@id='BidsLeftMargin']/..//div[5]//tr")for result in result_list:item = CsdnItem()title1 = result.xpath("./td[2]/span[1]/a/text()").extract_first()if title1:item["title"] = title1item["web_url"] = self.start_urls[0]#每一条bid的URLurls = self.domain + result.xpath("./td[2]/span[1]/a/@href").extract_first()item['bid_url'] = urls#将每条URL交给下一个函数进行页面解析yield Request(urls, callback=self.parse_content, meta={'item': item})def parse_content(self, response):item = response.meta['item']#这些都和案例一中的类似issuedate = response.xpath("//span[(text()='Publication Date/Time:')]/following::span[1]/text()").extract_first()item['issuedate'] = issuedateexpireDate = response.xpath("//span[(text()='Closing Date/Time:')]/following::span[1]/text()").extract_first()#之所以在截至日期这里多写一个if判断,是因为小编发现有些bids里面的截止日期是open util contracted#所以我们遇到这种情况就设置截止日期为明天if 'Open Until Contracted' in expireDate:#就是那系统现在的时间 + 一天 = 明天expiredate1 = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime('%m/%d/%Y')else:expiredate1 = expireDateitem['expiredate'] = expiredate1#我们将要下载的附件放入一个列表里面file_list = []file_list1 = response.xpath("//div[@class='relatedDocuments']/a/@href").extract()if file_list1:#有的标书会有不止一个附件,所以这里用for循环for listurl in file_list1:file_list.append(self.domain + listurl)item['file_urls'] = file_listyield item

接下来是setting.py文件:

# Obey robots.txt rules
ROBOTSTXT_OBEY = False  #将这行改为False
ITEM_PIPELINES = {'scrapy.pipelines.files.MyFilesPipeline':1   #调用scrapy自带的pipelines用于下载文件
}
FILES_STORE = '/Users/agnes/Downloads'  #这是下载的文件的存储路径

在terminal中运行代码:
scrapy crawl warrensburg

运行完后发现,文件根本没被下载下来,然后发现warning中显示301,那么这是什么问题呢??
因为 MEDIA_ALLOW_REDIRECTS 这个问题,在自带的FilesPipeline中这项默认是False的,那么要将这项改为True就可以啦。。。修正后的setting.py代码:

# Obey robots.txt rules
ROBOTSTXT_OBEY = False  #将这行改为False
ITEM_PIPELINES = {'scrapy.pipelines.files.MyFilesPipeline':1   #调用scrapy自带的pipelines用于下载文件
}
FILES_STORE = '/Users/agnes/Downloads'  #这是下载的文件的存储路径
MEDIA_ALLOW_REDIRECTS = True

运行后又发现,下载下来的文件名称是一串‘乱码’,而且没有文件后缀,那么我们现在来解决这个问题,我们先来看一下scrapy自带的FilesPipeline的源码:

其中的file_download函数调用了file_path函数,给出了文件的path,那么我们现在将这个file_download函数重写,让它可以获取文件类型并给出新的path,我们打开pipelines.py这个文件:

from scrapy.pipelines.files import FilesPipeline,BytesIO,md5sum  #这些都要导入
from urllib import parse
import reclass MyFilesPipeline(FilesPipeline):  #在FilesPipeline的基础上创建了自己的pipelinedef file_downloaded(self, response, request, info):  #函数名称和原FilesPipeline中的一样pattern = re.compile(r'filename=(.*)')    #文件名就是filename后面的字符串#利用Content-Disposition获取文件类型,containFileName = response.headers.get('Content-Disposition').decode('utf-8')    if not containFileName:containFileName = response.headers.get('content-disposition').decode('utf-8')#根据pattern在containFileName中找对应的字符串file_name1 = pattern.search(containFileName).group(1)  #解码,例如文件名里边带有的%20,通过解码可以转换成空格,如果没有这步,生成的文件名称则带有%20,这行可以删掉自己试试file_name2 = parse.unquote(file_name1)path = 'full/%s' % (file_name2)  #新的path在full文件夹中buf = BytesIO(response.body)  #以下这些照写checksum = md5sum(buf)buf.seek(0)self.store.persist_file(path, buf, info)return checksum

然后改下setting.py:

# Obey robots.txt rules
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {'CSDN.pipelines.MyFilesPipeline':1
}
FILES_STORE = '/Users/agnes/Downloads'
MEDIA_ALLOW_REDIRECTS = True

在terminal中运行代码:
scrapy crawl warrensburg

我们找到文件存储的路径,打开full文件夹,结果如图:

名称是根据path生成的,大家的结果可能跟我不一样,因为标书会实时更新,你们爬取下来的文件也会和我的不一样。

Python 爬虫案例(二)--附件下载相关推荐

  1. Python爬虫案例:批量下载超清画质手机壁纸

    目录 前言 开发环境 模块使用 基本流程: 一. 数据来源分析 二. 代码实现步骤: 完整代码 1. 发送请求 2. 获取数据 3. 解析数据 4. 保存数据 效果演示 前言 开发环境 Python ...

  2. Python爬虫【二】爬取PC网页版“微博辟谣”账号内容(selenium同步单线程)

    专题系列导引   爬虫课题描述可见: Python爬虫[零]课题介绍 – 对"微博辟谣"账号的历史微博进行数据采集   课题解决方法: 微博移动版爬虫 Python爬虫[一]爬取移 ...

  3. python爬虫案例-Python爬虫案例集合

    原标题:Python爬虫案例集合 urllib2 urllib2是Python中用来抓取网页的库,urllib2 是 Python2.7 自带的模块(不需要下载,导入即可使用) 在python2.x里 ...

  4. python爬虫案例——糗事百科数据采集

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--糗事百科数据采集 通过python实现糗事百科页面的内容采集是相对来说比较容易的,因为糗事百科不需要登陆,不需要coo ...

  5. python爬虫案例——csdn数据采集

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--csdn数据采集 通过python实现csdn页面的内容采集是相对来说比较容易的,因为csdn不需要登陆,不需要coo ...

  6. Python爬虫(二)

    Python爬虫(二) 一.请求对象的定制-User-Agent反爬机制 请求对象的定制:由于urlopen方法中没有字典类型的数据存储,所以headers不能直接存储进去 请求对象的定制的目的:是为 ...

  7. python爬虫简单实例-最简单的Python爬虫案例,看得懂说明你已入门,附赠教程

    原标题:最简单的Python爬虫案例,看得懂说明你已入门,附赠教程 这是最简单的Python爬虫案例,如果你能看懂,那么请你保持信心,因为你已经入门Python爬虫,只要带着信心和努力,你的技术能力在 ...

  8. python编程案例教程答案-python编程案例教程pdf下载

    python编程案例教程pdf下载内容摘要 python编程案例教程pdf下载教程,巧妙的谋划,巧妙的计谋.娄底电脑教程,巧克力奶茶等都是理想的增肥品.巧克力麦片等等,南宁街舞教程,巧克力成为一种&q ...

  9. 转 Python爬虫入门二之爬虫基础了解

    静觅 » Python爬虫入门二之爬虫基础了解 2.浏览网页的过程 在用户浏览网页的过程中,我们可能会看到许多好看的图片,比如 http://image.baidu.com/ ,我们会看到几张的图片以 ...

最新文章

  1. 直线轨道上声音延迟信号分析
  2. linux shell ls 输出存进数组变量
  3. USB 之三 常用抓包/协议分析工具(Bus Hound、USBlyzer、USBTrace、USB Monitor Pro等)
  4. 如何成为一个设计师和程序员混合型人才
  5. RUNOOB python练习题44
  6. Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition
  7. 缓存与数据库的一致性
  8. python写入txt,读取txt,拷贝txt文件
  9. 由《速7》谈起 付费将成互联网主流?
  10. IOS PhoneGap项目调用NATIVE
  11. 虚拟化云计算-centos7上使用virt-manager安装虚拟机
  12. 数值分析(2)-多项式插值: 拉格朗日插值法
  13. 利用npm命令创建一个Vue项目并安装依赖
  14. java 主流框架_java的三大主流框架介绍
  15. 常见容错机制:failover、failback、failfast、failsafe
  16. http协议get请求方法和post请求方法的区别
  17. linux挂载40t硬盘,Centos支持40T磁盘阵列MD1200
  18. 正则表达式 - 常用正则表达式
  19. carla学习笔记(二)
  20. 【Kafka笔记】4.Kafka API详细解析 Java版本(Producer API,Consumer API,拦截器等)

热门文章

  1. 国家政策对计算机编程政策,孩子的未来道路!2019年,国家为编程教育发布的22项政策都在这了...
  2. HTML5商业教育培训机构网站模板
  3. Android编译C/C++代码,编译出的so文件给别的项目用,CMakeLists.txt编译,请放弃Android.mk!
  4. 中英对照 关于计算机的科技英语,《计算机专业英语》中英文对照 .pdf
  5. UIPro实例讲解之QQ2014 UI模仿系列五 - 聊天气泡
  6. mysql日期用什么类型_mysql存储日期使用什么类型
  7. 虚拟化技术之虚拟化技术介绍及Xen的应用实现
  8. html编写百度页面,百度首页的百度一下怎么用html做?
  9. linux 重启php,Linux 重启命令是什么?
  10. PerformanceCounter简述及用法