一、創(chuàng)建項(xiàng)目
開始之前我們先建立項(xiàng)目
1、命令行輸入scrapy startproject dangdang創(chuàng)建dangdang項(xiàng)目文件夾
2、命令行輸入cd dangdang 進(jìn)入剛剛創(chuàng)建的目錄中
3、命令行輸入scrapy genspider spider "http://store.dangdang.com/282" 生成我們的爬蟲文件。

二、爬取子頁(yè)面鏈接
創(chuàng)建項(xiàng)目完畢后我們開始分析網(wǎng)頁(yè)(Chrome瀏覽器F12打開開發(fā)者模式),鼠標(biāo)移到我們需要的字段的位置,可以看到源碼,再?gòu)?fù)制XPath(如下圖)。
//*[@id="sidefloat"]/div[2]/div/div/map/area/@href
可以看到最左邊的分欄給出了所有的分類,那么我們依次爬取文學(xué)、小說等等每個(gè)頁(yè)面的內(nèi)容即可。
我們先記錄下這個(gè)的Xpath。

三、設(shè)置每本書要爬取的Item(Items.py)
那么對(duì)于每本書我們需要爬取的內(nèi)容已經(jīng)框選出來了
分別為價(jià)格、評(píng)論數(shù)量(銷量)、書名、作者、分類(也就是上一步獲取的內(nèi)容)

在項(xiàng)目文件中找到items.py定義上述字段。
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class DangdangItem(scrapy.Item):
# define the fields for your item here like:
#定義需要爬取的變量名
name=scrapy.Field()#定義保存書名的變量
author=scrapy.Field()#作者
price = scrapy.Field()#價(jià)格
comments=scrapy.Field()#銷量
category=scrapy.Field()#圖書分類
此外,我們還要獲取這幾個(gè)字段的Xpath。自己先悄悄地復(fù)制粘貼修改好。
四、爬蟲解析頁(yè)面(spider.py)
所以,對(duì)于整體的實(shí)現(xiàn),我們分兩步走,即按照二、三兩步分別要抓取的內(nèi)容進(jìn)行解析。
import scrapy
import re
from dangdang.items import DangdangItem
class SpiderSpider(scrapy.Spider):
name = 'spider'
allowed_domains = ['store.dangdang.com/282']
start_urls = ['http://store.dangdang.com/282']
def parse(self, response):
'''
爬取當(dāng)當(dāng)首頁(yè),獲取左邊懸浮窗口各個(gè)窗口的鏈接
循環(huán)解析每一個(gè)頁(yè)面內(nèi)容
'''
#獲取分類列表的鏈接
urls=response.xpath('//*[@id="sidefloat"]/div[2]/div/div/map/area/@href').extract()
#獲取分類名稱
categories=response.xpath('//*[@id="sidefloat"]/div[2]/div/div/map/area').extract()
for url,category in zip(urls,categories):#爬取分類鏈接的詳情頁(yè)
text = re.findall('title="(.*?)" alt',category)#正則匹配,提取分類關(guān)鍵字信息
for i in range(1,20):#爬取分頁(yè)信息
url_now=url+'&page_index='+str(i)#構(gòu)造每一頁(yè)的鏈接
#調(diào)用解析單頁(yè)的函數(shù)進(jìn)行爬取
yield scrapy.Request(url=url_now,callback=lambda response, category=text : self.parse_subpage(response,category), dont_filter=True)
def parse_subpage(self,response,category):
'''
獲取每一頁(yè)的各個(gè)商品的信息。
我們將每一個(gè)商品作為一個(gè)item
'''
#獲取每一面的圖書數(shù)量(這個(gè)不寫也可,去網(wǎng)站數(shù)一數(shù)就知道是24個(gè))
length= len(response.xpath('//*[@id="component_0__0__8395"]/li/a/img').extract())
for i in range(0,length+1):
item = DangdangItem()
item['name']=response.xpath('//*[@id = "component_0__0__8395"] /li[{}]/p[2]/a/text()'.format(i)).extract()
item['author']=response.xpath('//*[@id="component_0__0__8395"]/li[{}]/p[5]/text()'.format(i)).extract()
item['price']=response.xpath('//*[@id="component_0__0__8395"]/li[{}]/p[1]/span[1]/text()'.format(i)).extract()
item['comments']=response.xpath('//*[@id="component_0__0__8395"]/li[{}]/p[4]/a/text()'.format(i)).extract()
item['category']=category
yield item
這樣我們一個(gè)整體的抓取工作就完成了。但是數(shù)據(jù)現(xiàn)在只是抓取下來,并沒有保存到本地目錄來。所以接下來我們還要設(shè)置保存方法。
五、將爬取內(nèi)存保存至本地(piplines.py)
通過設(shè)置piplines.py管道文件,使得我們可以在每次調(diào)用Item之后,將item自動(dòng)保存到我們指定的本地位置,以下兩種保存方法任選一種都可以保存成功
1、保存數(shù)據(jù)到MongoDB
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import pymongo
class DangdangPipeline(object):
def __init__(self):
# 連接數(shù)據(jù)庫(kù)
self.client = pymongo.MongoClient(host='127.0.0.1', port=27017)#連接MongoDB
self.test = self.client['dangdang']#創(chuàng)建數(shù)據(jù)庫(kù)dangdang
self.post = self.test['book']
def process_item(self, item, spider):
data = dict(item)#插入數(shù)據(jù)之前需要把字段轉(zhuǎn)換成字典形式
flag=1#判斷是否為空,默認(rèn)為1,表示不為空
for key,value in data.items():
if (value == []):
flag = 0
break
if(type(value)==list):
data[key]=value[0]
if(flag==1):
self.post.insert(data)#插入數(shù)據(jù)
# return item
2、保存到csv
import csv
class DangdangPipeline(object):
def __init__(self):
# csv文件的位置,無需事先創(chuàng)建
store_file = "dangdang.csv"
self.file = open(store_file, 'a+', encoding="utf-8",newline = '')
# csv寫法
self.writer = csv.writer(self.file, dialect="excel")
def process_item(self, item, spider):
# 判斷字段值不為空再寫入文件
if(len(item['name'])!=0):
self.writer.writerow([item['name'],item['author'] ,item['price'], item['comments'], item['category']])
return item
pipline寫完之后我們還需要修改setting.py使得管道文件生效,這樣我們的爬取工作就告一段落了。

六、查看、清洗數(shù)據(jù),開始數(shù)據(jù)分析
這樣我們一個(gè)整體的就做好了
我們新建一個(gè)代碼文件來讀取爬到的數(shù)據(jù)。

相關(guān)的爬蟲源碼如下↓↓↓,關(guān)注公眾號(hào)回復(fù)0001,即可獲得爬蟲+數(shù)據(jù)分析源碼:
