####1、安装scrapy
建议:最好在新的虚拟环境里面安装scrapy
注意:博主是在 Ubuntu18.04 + Python3.6 环境下进行开发的,如果遇到安装scrapy不成功请自行百度/谷歌解决
pip install scrapy
顺便装上iPython 这样方便操作scrapy shell
pip install ipython
####2、scrapy入门讲解
先附上爬取原理图
(1)创建项目
通过指令来进行创建的
scrapy startproject firstSpider(项目名称)
(2)项目目录结构
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对象,简单跑一把
来到终端下:
cd firstSpider/firstSpider/spiders
scrapy crawl qiubai
根据response获取网页内容
response.text 字符串类型
response.body 二进制类型
(5)运行,直接通过命令导出json格式
scrapy crawl qiubai -o qiubai.json
scrapy crawl qiubai -o qiubai.xml
scrapy crawl qiubai -o qiubai.csv
(6)scrapy 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)
####3、实战-爬取校花网图片资源
1、settings.py文件的配置
# 使用的请求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,
}
####剩余配置默认即可
2、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()
3、关键爬虫文件xiaohua.py的处理
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)
4、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()
5、最后附上项目地址
git@gitee.com:aeasringnar/xiaohuaproject.git