pip install scrapy
# projectname为项目名称,可自定义
scrapy startproject projectname
创建项目后会看到以项目名称为名的目录,目录下面的结构如下所示
projectname/
scrapy.cfg # 配置文件
projectname/ # 爬虫模块文件夹
__init__.py
items.py # items定义文件
middlewares.py # 中间件middlewares文件
pipelines.py # 项目管道pipelines文件
settings.py # 设置settings文件
spiders/ # 爬虫文件夹
__init__.py
在编写前首先要了解scrapy的工作原理
提取数据前要先定位元素,scrapy中可以使用xpath进行定位,也可以使用CSS进行定位,实例如下
response.xpath('//span/text()').get()
response.css('span::text').get()
详细的这里不做记录了,请百度。
爬虫写好后当然就是要迫不及待的执行试试了
# projectname为项目名称
scrapy crawl projectname
# 在shell中执行scrapy,URL为要爬取的网址
scrapy shell URL
为了学习这里就使用豆瓣进行测试,实现将图书详细信息页面的信息进行存储,我是用《百年孤独》页面来做测试的,其网址为https://book.douban.com/subject/6082808
我创建的项目名称为booksearch,使用的爬虫名为book,爬取后,会解析出书名、作者、出版社、原作名、译者、出版年、页数、定价、装帧、丛书、ISBN码、评分,并以json的形式存到book.json文件中,读取json文件如下图所示
下面上代码
项目文件结构
booksearch/
scrapy.cfg # 配置文件
booksearch/ # 爬虫模块文件夹
__init__.py
items.py # items定义文件
middlewares.py # 中间件文件
pipelines.py # 项目管道文件
settings.py # 设置文件,设置headers、执行优先级、robots开关等设置
spiders/ # 爬虫文件夹
__init__.py
book_spider.py # 爬虫文件,负责爬取图书页面
爬虫文件
# -*- coding: utf-8 -*-
import scrapy
from booksearch.items import BooksearchItem
class BookSpider(scrapy.Spider):
name = 'book'
allowed_domains = ['book.douban.com']
def __init__(self,url=None, *args, **kwargs):
super(BookSpider, self).__init__(*args, **kwargs)
self.start_urls = [r'https://book.douban.com/subject/6082808/',]
def parse(self, response):
print('开始处理')
item = BooksearchItem()
# 书名
item['title'] = response.xpath("//span[@property='v:itemreviewed']/text()").extract()[0]
# 获取图书信息后解析
temp_dict = {}
temp_list = []
tmp = response.xpath('//div[@id="info"]')
for i in tmp.xpath('.//text()').extract():
i=i.replace(' ', '').strip('\n').strip()
if len(i)>0:
if '作者' in i:
i = '作者:'
if '译者' in i:
i = '译者:'
if ':' not in i:
i = i + ';'
if i == ':':
continue
temp_list.append(i.replace(' ', '').strip('\n').strip())
temp_str = ''.join(temp_list)
temp_list2 = temp_str.split(';')
for i in temp_list2:
if len(i)>0:
temp_dict.update({i.split(':')[0]:i.split(':')[1]})
if '作者' in temp_dict.keys():
item['author'] = temp_dict['作者'] # 作者
if '出版社' in temp_dict.keys():
item['publisher'] = temp_dict['出版社'] # 出版社
if '原作名' in temp_dict.keys():
item['original_title'] = temp_dict['原作名'] # 原作名
if '译者' in temp_dict.keys():
item['translator'] = temp_dict['译者'] # 译者
if '出版年' in temp_dict.keys():
item['pub_date'] = temp_dict['出版年'] # 出版年
if '页数' in temp_dict.keys():
item['pages'] = temp_dict['页数'] # 页数
if '定价' in temp_dict.keys():
item['price'] = temp_dict['定价'] # 定价
if '装帧' in temp_dict.keys():
item['bingding'] = temp_dict['装帧'] # 装帧
if '丛书' in temp_dict.keys():
item['series'] = temp_dict['丛书'] # 丛书
if 'ISBN' in temp_dict.keys():
item['isbn'] = temp_dict['ISBN'] # ISBN码
# 获取评分
item['star'] = response.xpath("//strong/text()").get()
yield item
itmes文件
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class BooksearchItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 书名
author = scrapy.Field() # 作者
publisher = scrapy.Field() # 出版社
original_title = scrapy.Field() # 原作名
translator = scrapy.Field() # 译者
pub_date = scrapy.Field() # 出版年
pages = scrapy.Field() # 页数
price = scrapy.Field() # 定价
bingding = scrapy.Field() # 装帧
series = scrapy.Field() # 丛书
isbn = scrapy.Field() # ISBN码
star = scrapy.Field() # 评分
项目管道文件
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
class BooksearchPipeline(object):
def process_item(self, item, spider):
print('开始存储爬取内容')
line = json.dumps(dict(item)) + "\n"
print(line)
with open('book.json', 'w') as f:
f.write(line)
return item