明确要抓取的信息
抓取数据:各级分类的名称
和URL
大分类名称和url
中分类名称和url
小分类名称和url
抓取数据
商品名称
商品价格
商品评论数量
商品店铺
商品促销
商品版本
商品图片的ULR
平台:window+Linux
开发语言:python3
开发工具:pycharm
技术选择:
属于全网爬虫,抓取的页面非常多,考虑到效率,使用scrapy+scrapy_redis
数据量很多,选择MongoDB
广度优先策略,将类别和商品信息的抓取分开
优点:逐步实现,高稳定性
1.创建爬虫项目
2.根据需求,定义数据模型
3.实现分类爬虫
4.保存分类信息
5.实现商品爬虫
6.保存商品信息
7.实现随机User-Agent和代理IP下载器中间,解决IP反爬
类别数据模型类(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()
商品数据模型类(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()
?
目标:确定分类信息的url
步骤:
进入到京东主页
右击检查,全局搜索分类信息,如“超薄电视”
确定分类的url:“https://dc.3.cn/category/get”
url分析
get请求
查询参数:
callback: getCategoryCallback
创建爬虫
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: