参考scrapy中文教程,http://scrapy-chs.readthedocs.io/zh_CN/1.0/
一、环境:
python3.6
scrapy 1.5
Eclipse+Pydev
python配置环境变量,用于scrapy创建项目、执行爬取:
Path:C:\Users\Administrator\AppData\Local\Programs\Python\Python36\;C:\Users\Administrator\AppData\Local\Programs\Python\Python36\Scripts;C:\Users\Administrator\AppData\Local\Programs\Python\Python36\Lib\site-packages\OpenSSL
二、需求:
1、爬取慕课网:http://www.imooc.com/course/list的课程信息
2、课程信息内容:课程url、课程标题 课程访问人数、课程简介,存储json文件;
3、课程图片下载固定目录下
三、实现过程:
1、在项目根目录下,打开cmd,执行命令,创建项目
scrapy startproject scrapytest01
scrapy.cfg: 项目的配置文件 scrapytest01/: 该项目的python模块。 scrapytest01/items.py: 项目中的item文件,用于爬取的数据结构定义,且存储数据的容器 scrapytest01/pipelines.py: 项目中的pipelines文件,用于处理数据的过程,如清理、去重、验证、存储等. scrapytest01/settings.py: 项目的设置文件,提供了定制Scrapy组件的方法。可以控制包括核心(core),插件(extension),pipeline及spider组件。. scrapytest01/spiders/: 放置spider代码的目录,用于如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item).
2、删除item.py,重新自定义一个需要爬取的数据结构或容器,需要定义课程标题、课程url、课程标题图片、课程描述、访问课程的人数,CourseItems.py
# -*- coding: utf-8 -*- ''' Created on 2018年6月4日 @author: Administrator ''' import scrapy class CourseItems(scrapy.Item): #课程标题 title=scrapy.Field() #课程url url=scrapy.Field() #课程标题图片 image_url=scrapy.Field() #课程描述 introduction=scrapy.Field() #访问课程的人数 studentnum=scrapy.Field()
3、在spider目录下,创建MySpider.py,用于爬取网站中的课程信息
# -*- coding: utf-8 -*- ''' Created on 2018年6月4日 @author: Administrator ''' import scrapy from scrapytest01.CourseItems import CourseItems class MySpider(scrapy.Spider): #用于区别Spider name='MySpider' #允许访问的域 allowed_domains=['imooc.com'] #爬取的网址 start_urls=["http://www.imooc.com/course/list"] #爬取的方法 def parse(self,response): #实例一个容器保存爬取的信息 item = CourseItems() #这部分是爬取部分,使用xpath的方式选择信息,具体方法根据网页结构而定 #先获取每个课程的div for box in response.xpath('//div[@class="course-card-container"]/a[@target="_blank"]'): #获取每个div中的课程路径 item['url'] = 'http://www.imooc.com' + box.xpath('.//@href').extract()[0] #获取div中的课程标题 item['title'] = box.xpath('.//div[@class="course-card-content"]/h3/text()').extract()[0].strip() #获取div中的标题图片地址 item['image_url'] = 'http:' +box.xpath('.//@src').extract()[0] #获取div中的学生人数 item['studentnum'] = box.xpath('.//span/text()').extract()[0].strip()[:-3] #获取div中的课程简介 item['introduction'] = box.xpath('.//p/text()').extract()[0].strip() #返回信息 yield item # #跟进url # #获取下一页的url信息 # url=response.xpath("//a[contains(text(),'下一页')]/@href").extract() # if url : # #将信息组合成下一页的url # page = 'http://www.imooc.com' + url[0] # #返回url # yield scrapy.Request(page, callback=self.parse) # #url跟进结束
4、删除pipelines.py,重新定义一个爬取的课程信息,存储json文件中
# -*- coding: utf-8 -*- ''' Created on 2018年6月4日 @author: Administrator ''' from scrapy.exceptions import DropItem import json class MyPipeline(object): def __init__(self): self.file=open('data.json','w',encoding='utf-8') def process_item(self, item, spider): #读取item中的数据 line = json.dumps(dict(item), ensure_ascii=False) + "\n" #写入文件 self.file.write(line) #返回item return item #该方法在spider被开启时被调用。 def open_spider(self, spider): pass #该方法在spider被关闭时被调用。 def close_spider(self, spider): pass
5、重新定义数据处理类,把爬取的图片url进行图片下载处理,并且存储到指定目录下
# -*- coding:utf-8 -*- import scrapy from scrapy.contrib.pipeline.images import ImagesPipeline from scrapy.exceptions import DropItem class ImgPipeline(ImagesPipeline): #通过抓取的图片url获取一个Request用于下载 def get_media_requests(self, item, info): #返回Request根据图片图片url下载 yield scrapy.Request(item['image_url']) #当下载请求完成后执行该方法 def item_completed(self, results, item, info): #获取下载地址 image_path = [x['path'] for ok, x in results if ok] #判断是否成功 if not image_path: raise DropItem("Item contains no images") #将地址存入item item['image_path'] = image_path return item
6、在setting.py中,添加ITEM_PIPELINES 添加爬取数据处理类的路径,以及执行顺序;添加IMAGES_STORE 图片下载的目录
ITEM_PIPELINES = { 'scrapytest01.MyPipelines.MyPipeline': 100, 'scrapytest01.ImgPipelines.ImgPipeline': 1, }
IMAGES_STORE = 'C:\\Users\\Administrator\\Desktop\\img'
7、执行爬取
scrapy crawl MySpider
四、结果: