1.1 目標
-
明確要抓取的信息
1.2 目標分解
1.2.1 抓取首頁的分類信息
-
抓取數據:各級分類的
名稱
和URL
-
大分類名稱和url
-
中分類名稱和url
-
小分類名稱和url
-
1.2.2 抓取商品信息
-
抓取數據
-
商品名稱
-
商品價格
-
商品評論數量
-
商品店鋪
-
商品促銷
-
商品版本
-
商品圖片的ULR
-
2、開發環境與技術選擇
-
平台:window+Linux
-
開發語言:python3
-
開發工具:pycharm
-
技術選擇:
-
屬於全網爬蟲,抓取的頁面非常多,考慮到效率,使用scrapy+scrapy_redis
-
數據量很多,選擇MongoDB
-
3、京東全網爬蟲實現步驟
-
廣度優先策略,將類別和商品信息的抓取分開
-
優點:逐步實現,高穩定性
-
3.1 總體設計
3.2 實現步驟
-
1.創建爬蟲項目
-
2.根據需求,定義數據模型
-
3.實現分類爬蟲
-
4.保存分類信息
-
5.實現商品爬蟲
-
6.保存商品信息
-
7.實現隨機User-Agent和代理IP下載器中間,解決IP反爬
4、數據模型
4.1 類別數據模型
-
類別數據模型類(Category(scrapy.Item)):用於存儲類別信息字段
-
b_cate
-
b_cate_name:大類別名稱
-
b_cate_url:大類別url
-
-
m_cate
-
m_cate_name:中類別名稱
-
m_cate_url:中類別url
-
-
s_cate
-
s_cate_name:小類別名稱
-
s_cate_url:小類別url
-
-
-
代碼
class Category(scrapy.Item):
b_cate = scrapy.Field()
m_cate = scrapy.Field()
s_cate = scrapy.Field()
4.2 商品數據模型
-
商品數據模型類(Product(scrapy.Item)):用於存儲商品信息字段
-
product_category:商品類別
-
product_sku_id:商品ID
-
product_name:商品名稱
-
product_img_url:商品圖片url
-
product_options:商品版本
-
product_shop:商品店鋪
-
product_comments:商品評論數量
-
product_ad:商品促銷信息
-
product_price:商品價格
-
product_book_info:圖書信息,作者,出版社
-
-
代碼:
class Product(scrapy.Item):
product_category = scrapy.Field()
product_sku_id = scrapy.Field()
product_name = scrapy.Field()
product_img_url = scrapy.Field()
product_price = scrapy.Field()
product_options = scrapy.Field()
product_shop = scrapy.Field()
product_comments = scrapy.Field()
product_ad = scrapy.Field()
product_book_info = scrapy.Field()
5、分類爬蟲
5.1 確定目標url
-
目標:確定分類信息的url
-
步驟:
-
進入到京東主頁
-
右擊檢查,全局搜索分類信息,如“超薄電視”
-
確定分類的url:“https://dc.3.cn/category/get”
-
-
url分析
-
get請求
-
查詢參數:
-
callback: getCategoryCallback
-
-
5.2 創建爬蟲
-
創建爬蟲
-
scrapy genspider cate jd.com
-
-
指定起始url
-
https://dc.3.cn/category/get
-
-
解析數據,交給引擎
-
編碼分析
-
返回數據編碼為‘GBK’
-
-
url分析
有三類數據格式
-
1316-1381|面部護膚||0
-
帶有一個
-
的字符,需要拼接“https://channel.jd.com/{}.html”
-
list.jd.com/list.html?tid=1008668|游戲手機||0
-
完整的url,都帶有
jd.com
字符,不需要替換或拼接
-
-
1316-1381-1392|面膜||0
-
拼接url:“https://list.jd.com/list.html?cat=737,794,13701”,並且將
-
替換為,
-
有兩個
-
的字符,需要將-
替換為,
,且添加字符https://list.jd.com/list.html?cat=
-
-
-
-
代碼
import scrapy
import json
from jingdong.items import Category
class CateSpider(scrapy.Spider):
name = 'cate'
allowed_domains = ['dc.3.cn']
start_urls = ['https://dc.3.cn/category/get']
def get_name_and_url(self, cate_info, cate_name, cate_url):
cate = list()
if isinstance(cate_info, list):
for _ in cate_info:
item = dict()
item[cate_name] = _.split(r'|')[1]
url = _.split(r'|')[0]
if 'jd.com' in url:
item[cate_url] = "https://" + url
elif url.count("-") == 1:
item[cate_url] = 'https://channel.jd.com/{}.html'.format(url)
elif url.count("-") == 2:
item[cate_url] = 'https://list.jd.com/list.html?cat={}'.format(url.replace('-', ','))
cate.append(item)
return cate
if isinstance(cate_info, str):
item = dict()
item[cate_name] = cate_info.split(r'|')[1]
url = cate_info.split(r'|')[0]
if 'jd.com' in url:
item[cate_url] = "https://" + url
elif url.count("-") == 1:
item[cate_url] = 'https://channel.jd.com/{}.html'.format(url)
elif url.count("-") == 2:
item[cate_url] = 'https://list.jd.com/list.html?cat={}'.format(url.replace('-', ','))
cate.append(item)
return cate
def get_info_from_s(self, data):
n_cate_list = list()
s_cate_list = list()
if isinstance(data, list):
for _ in data:
# 獲取單個條目下的數據
name = _['n']
info = _["s"]
if name:
n_cate_list.append(name)
if info:
s_cate_list.append(info)
return n_cate_list, s_cate_list
if isinstance(data, dict):
name = data['n']
info = data["s"]
if name: