####一、安装scrapy
建议:最好在新的虚拟环境里面安装scrapy
注意:博主是在 Ubuntu18.04 + Python3.6 环境下进行开发的,若是遇到安装scrapy不成功请自行百度/谷歌解决php
pip install scrapy
顺便装上iPython 这样方便操做scrapy shellcss
pip install ipython
####二、scrapy入门讲解
先附上爬取原理图
(1)建立项目html
经过指令来进行建立的 scrapy startproject firstSpider(项目名称)
(2)项目目录结构python
firstSpider firstSpider spiders 爬虫目录(写代码位置) __init__.py 表示这是一个Python模块 first.py 爬虫文件 __init__.py items.py 定义数据结构地方 middlewares.py 中间件 pipelines.py 管道文件 settings.py 项目配置文件 scrapy.cfg
经过指令建立爬虫文件 cd firstSpider/firstSpider scrapy genspider qiubai "www.qiushibaike.com" 那么就会在firstSpider/firstSpider/spiders里面自动建立一个qiubai.py name: 爬虫的名字,启动的时候根据爬虫的名字启动项目 allowed_domains:容许的域名,就是爬取的时候这个请求要不要发送,若是是该容许域名之下的url,就会发送,若是不是,则过滤掉这个请求,这是一个列表,能够写多个容许的域名 start_urls:爬虫起始url,是一个列表,里面能够写多个,通常只写一个 def parse(self, response): 这个函数很是重要,就是你之后写代码的地方,parse函数名是固定的,当收到下载数据的时候会自动的调用这个方法,该方法第二个参数为response,这是一个响应对象,从该对象中获取html字符串,而后解析之。【注】这个parse函数必须返回一个可迭代对象
(3)定制items.py,其实就是您的数据结构,格式很是简单,复制粘贴便可
(4)打印response对象,简单跑一把git
来到终端下: cd firstSpider/firstSpider/spiders scrapy crawl qiubai 根据response获取网页内容 response.text 字符串类型 response.body 二进制类型
(5)运行,直接经过命令导出json格式web
scrapy crawl qiubai -o qiubai.json scrapy crawl qiubai -o qiubai.xml scrapy crawl qiubai -o qiubai.csv
(6)scrapy shell 的使用shell
scrapy shell 运行在终端的工具,用来调试scrapy 简单使用 # 注意不能在已近建立好的scrapy目录下操做,不然返回的response为 none (1)scrapy shell "http://www.xiaohuar.com/hua/" response对象 属性 text:字符串格式的html body:二进制格式的html url:所请求的url status:响应的状态码 方法: xpath(): 根据xpath路径获取符合的路径全部selector对象(是scrapy本身封装的一个类的对象)的列表 css(): 根据选择器获取符合选择器要求的全部selector对象的列表 获取内容的时候要这么写 #detail-list > li .header > a > div > .name::text 获取属性的方法要这么写 #detail-list > li .header > a > div > .name::attr("data-src") 下面接着extract()便可 通常不使用这个,由于中间scrapy会将这个选择器给翻译成xpath再去解析 selector对象 xpath('./'): 从当前节点向下开始查找 css(): 和上面的response的方式同样 extract(): 将对象转化为unicode字符串,供你的代码使用 extract_first(): 理论上至关于上面的 name_list.extract()[0] == name_list.extract_first() 但实际上,extract_first()要比extract()强大,若是xpath没有获取到内容,extract_first()会返回None (2)item对象 官方的这个Item其实就是一个类字典的对象,或者你就能够叫作它就是一个字典,用的时候和字典的用法如出一辙 将这个对象转化为字典 pp = dict(p)
####三、实战-爬取校花网图片资源
一、settings.py文件的配置json
# 使用的请求ua # Crawl responsibly by identifying yourself (and your website) on the user-agent USER_AGENT = 'Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1' # 是否遵循国际爬虫条例,我的写的爬虫不须要遵循 # Obey robots.txt rules ROBOTSTXT_OBEY = False # 设置的请求头 # Override the default request headers: DEFAULT_REQUEST_HEADERS = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', # 'Accept-Language': 'en', } # Configure item pipelines # See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html # 表示使用管道 这里300表示处理的优先级 # 你也能够本身再写一部分管道,而后设置优先级处理 ITEM_PIPELINES = { 'huaproject.pipelines.HuaprojectPipeline': 300, } ####剩余配置默认便可
二、items.py文件的处理数据结构
import scrapy class HuaprojectItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 须要的数据如今这里制定好,由于在settings里面已近设置好了,因此能够和pipelines联系在一块处理数据 # 图片连接 image_url = scrapy.Field() # 名字 name = scrapy.Field() # 大学 school = scrapy.Field() # 喜欢数 like = scrapy.Field()
三、关键爬虫文件xiaohua.py的处理app
import scrapy # 导入数据结构类 from huaproject.items import HuaprojectItem class XiaohuaSpider(scrapy.Spider): name = 'xiaohua' allowed_domains = ['www.xiaohuar.com'] # 基础url url = 'http://www.xiaohuar.com/list-1-' # 爬取的起始页 page = 0 # 爬取的起始url start_urls = ['http://www.xiaohuar.com/hua/list-1-0.html'] # 定义的方法,注意这个方法名不能修改,传入的参数也不能修改,不然会出错 def parse(self, response): # print(100) # 解析全部校花,获取指定内容 div_list = response.xpath('//div[@class="item masonry_brick"]') # print(div_list) # 遍历上面全部的div,找到指定的内容便可 for div in div_list: # 建立item对象 就是咱们在items里面定义的类 item = HuaprojectItem() image_url = div.xpath('./div[@class="item_t"]/div[@class="img"]/a/img/@src').extract_first() # 处理周半仙图片是以.php结尾的 if image_url.endswith('.php'): image_url = image_url.replace('.php', '.jpg') # 拼接图片的全路径 image_url = 'http://www.xiaohuar.com' + image_url name = div.xpath('./div[@class="item_t"]/div[@class="img"]/span[@class="price"]/text()').extract_first() school = div.xpath('./div[@class="item_t"]/div[@class="img"]/div[@class="btns"]/a/text()').extract_first() like = div.xpath('./div[contains(@class,"item_b")]//em[@class="bold"]/text()').extract_first() # 将上面提取的属性保存到对象中 item['image_url'] = image_url item['name'] = name item['school'] = school item['like'] = like # 将该item对象返回 yield item # url = 'http://www.xiaohuar.com/hua/list-1-' # page = 0 # 当处理完第一页的时候,要接着发送请求,处理下一页 self.page += 1 if self.page <= 11: url = self.url + str(self.page) + '.html' # 再次的发送请求,而且指定回调处理函数进行处理对应的请求 yield scrapy.Request(url=url, callback=self.parse)
四、pipelines.py文件的处理
import json import os import urllib.request class HuaprojectPipeline(object): # 重写构造方法,在这打开文件 def __init__(self): # 文件的打开写到这里,仅会执行一次 self.fp = open('xiaohua.json', 'w', encoding='utf-8') def open_spider(self, spider): pass # 在这里处理每个item def process_item(self, item, spider): # 将这个对象转化为字典 obj = dict(item) # 将图片下载到本地 # 获取当前目录的绝对路径 file_root_path = os.path.dirname(os.path.abspath(__file__)) # 拼接须要保存的路径 img_dir_path = os.path.join(file_root_path, 'spiders/images') # 判断这个目录是否已经存在,不存在就自动建立 is_have_img_dir = os.path.exists(img_dir_path) if is_have_img_dir: pass else: os.mkdir(img_dir_path) # 获取图片后缀名 suffix = os.path.splitext(obj['image_url'])[-1] # 拼接文件名 filename = obj['like'] + '_' + obj['school'] + '_' + obj['name'] + suffix # 将文件路径和文件名拼接出来文件的全路径 filepath = os.path.join(img_dir_path, filename) # 下载图片 urllib.request.urlretrieve(obj['image_url'], filepath) # 将obj转化为字符串 string = json.dumps(obj, ensure_ascii=False) self.fp.write(string + '\n') return item # 重写这个方法,在关闭spider的时候将文件资源关闭 def close_spider(self, spider): self.fp.close()
五、最后附上项目地址
git@gitee.com:aeasringnar/xiaohuaproject.git