苏宁图书(https://book.suning.com/)

目标:

1、图书一级分类

2、图书二级分类

3、图书三级分类

4、图书名字

5、图书作者

6、图书价格

7、通过Scrapy获取以上数据并存储在MongoDB中

步骤:

1、创建项目

2、编写爬虫

  • 发送主页请求,获取响应
  • 利用xpath提取一级、二级、三级分类的名称和三级分类对应的图书列表页url
  • 对图书列表页发送请求,获取响应
  • 利用xpath提取图书的名称、价格信息以及下一页url

3、运行爬虫,保存数据

问题:

1、价格信息的获取,测试发现价格信息不在请求的列表页中。通过抓包确定了价格信息所在的URL,并且该URL随着网页的滚动动态生成,

于是通过对比多个URL,并尝试不断精简,最终发现规律:

url = "https://ds.suning.com/ds/generalForTile/{ }_-010-2-{ }-1--".format(prdid, shopid)

prdid, shopid可以在列表页中提取得到,进而构造出每本图书的价格地址

2、列表页下一页URL,通过判断每一页是否有“下一页”这个标志进行翻页循环

 代码:

  • item.py
import scrapy

class BookItem(scrapy.Item):
book_class1 = scrapy.Field()
book_class2 = scrapy.Field()
book_class3 = scrapy.Field()
book_name = scrapy.Field()
book_author = scrapy.Field()
book_price = scrapy.Field()
  • setting.py
BOT_NAME = 'book'

SPIDER_MODULES = ['book.spiders']
NEWSPIDER_MODULE = 'book.spiders' LOG_LEVEL = "WARNING"
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36' # Obey robots.txt rules
ROBOTSTXT_OBEY = True # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 # Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 # Disable cookies (enabled by default)
#COOKIES_ENABLED = False # Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = 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',
#} # Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'book.middlewares.BookSpiderMiddleware': 543,
#} # Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'book.middlewares.BookDownloaderMiddleware': 543,
#} # Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#} # Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'book.pipelines.BookPipeline': 300,
} # Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False # Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage' # MONGODB 主机名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口号
MONGODB_PORT = 27017
# 数据库名称
MONGODB_DBNAME = "book"
# 存放数据的表名称
MONGODB_SHEETNAME = "book"
  • pipeline.py
from itemadapter import ItemAdapter
import pymongo
from scrapy.utils.project import get_project_settings
settings = get_project_settings() class BookPipeline:
def __init__(self):
host = settings["MONGODB_HOST"]
port = settings["MONGODB_PORT"]
dbname = settings["MONGODB_DBNAME"]
sheetname = settings["MONGODB_SHEETNAME"]
# 创建MONGODB数据库链接
client = pymongo.MongoClient(host=host, port=port)
# 指定数据库
mydb = client[dbname]
# 存放数据的数据库表名
self.post = mydb[sheetname] def process_item(self, item, spider):
data = dict(item)
self.post.insert(data)
print(item)
return item
  • spider.py
import scrapy
from book.items import BookItem
import re
import json class SuningSpider(scrapy.Spider):
name = 'suning'
allowed_domains = ['suning.com']
start_urls = ['https://book.suning.com/'] def parse(self, response):
class1_list = response.xpath("//div[@class='menu-item'][position()<8]")
loc2 = "//div[@class='menu-sub'][{}]/div[@class='submenu-left']/p" # 二级分类定位
loc3 = "//div[@class='menu-sub'][{}]/div[@class='submenu-left']/ul/li" # 三级分类定位
for class1 in class1_list:
item = BookItem()
item["book_class1"] = class1.xpath(".//h3/a/text()").extract_first() # 一级分类
for class2 in response.xpath(loc2.format(class1_list.index(class1) + 1)):
item["book_class2"] = class2.xpath("./a/text()").extract_first() # 二级分类
for class3 in response.xpath(loc3.format(class1_list.index(class1) + 1)):
item["book_class3"] = class3.xpath("./a/text()").extract_first() # 三级分类
book_list_href = class3.xpath("./a/@href").extract_first() # 图书列表页url
yield scrapy.Request(book_list_href, callback=self.parse_book_list, meta={"item": item}) # 图书列表页请求方法
def parse_book_list(self, response):
# 通过meta参数实现item的传递
item = response.meta["item"]
book_list = response.xpath("//div[@class='img-block']/a")
for book in book_list:
prdid = eval(book.xpath("./@sa-data").extract_first())["prdid"]
shopid = eval(book.xpath("./@sa-data").extract_first())["shopid"]
# 构建价格信息所在的url
book_price_url = "https://ds.suning.com/ds/generalForTile/{}_-010-2-{}-1--".format(prdid, shopid)
# 图书详情页URL
book_href = "https:" + book.xpath("./@href").extract_first()
yield scrapy.Request(book_price_url, callback=self.parse_book_price, meta={"item": item})
yield scrapy.Request(book_href, callback=self.parse_book_detail, meta={"item": item}) # 下一页URL
next_url_tmp = response.xpath("//a[@title='下一页']/@href").extract_first()
if next_url_tmp is not None:
next_url = "https://list.suning.com" + next_url_tmp
yield scrapy.Request(next_url, callback=self.parse_book_list) # 图书价格获取方法
def parse_book_price(self, response):
item = response.meta["item"]
item["book_price"] = json.loads(response.text)["rs"][0]["price"] # 图书详情页处理方法
def parse_book_detail(self, response):
item = response.meta["item"]
# 图书名字
item["book_name"] = "".join(response.xpath("//div[@class='proinfo-title']/h1/text()").extract()).strip()
# 图书作者
author = response.xpath("//li[@class='pb-item']/text()").extract_first()
# 图书作者信息字符串处理
if author is not None:
item["book_author"] = re.sub(r"\n|\t|\s", "", author)
yield item

Scrapy项目_苏宁图书信息的更多相关文章

  1. Scrapy项目 - 实现豆瓣 Top250 电影信息爬取的爬虫设计

    通过使Scrapy框架,掌握如何使用Twisted异步网络框架来处理网络通讯的问题,进行数据挖掘和对web站点页面提取结构化数据,可以加快我们的下载速度,也可深入接触各种中间件接口,灵活的完成各种需求 ...

  2. Scrapy项目 - 实现斗鱼直播网站信息爬取的爬虫设计

    要求编写的程序可爬取斗鱼直播网站上的直播信息,如:房间数,直播类别和人气等.熟悉掌握基本的网页和url分析,同时能灵活使用Xmind工具对Python爬虫程序(网络爬虫)流程图进行分析.   一.项目 ...

  3. Scrapy项目_阳光热线问政平台

    目的: 爬取阳光热线问政平台问题中每个帖子的标题.详情URL.详情内容.图片以及发布时间 步骤: 1.创建爬虫项目 1 scrapy startproject yangguang 2 cd yangg ...

  4. pycharm创建scrapy项目教程及遇到的坑

    最近学习scrapy爬虫框架,在使用pycharm安装scrapy类库及创建scrapy项目时花费了好长的时间,遇到各种坑,根据网上的各种教程,花费了一晚上的时间,终于成功,其中也踩了一些坑,现在整理 ...

  5. scrapy(一)--Pycharm创建scrapy项目

    1.环境 操作系统:windows10. python版本:python3.6,Anaconda(将Anaconda3\Scripts;路径添加到环境变量Path中) pycharm:pycharm2 ...

  6. scrapy爬虫--苏宁图书

    实现业务逻辑如下: 1. 创建scrapy项目,并生成 爬虫2. 在suning.py中实现Schedul 和 Spider业务逻辑3. 修改start_urls为正确的初始请求地址4. 构造pars ...

  7. scrapy(一)建立一个scrapy项目

    本项目实现了获取stack overflow的问题,语言使用python,框架scrapy框架,选取mongoDB作为持久化数据库,redis做为数据缓存 项目源码可以参考我的github:https ...

  8. Python爬虫Scrapy(二)_入门案例

    本章将从案例开始介绍python scrapy框架,更多内容请参考:python学习指南 入门案例 学习目标 创建一个Scrapy项目 定义提取的结构化数据(Item) 编写爬取网站的Spider并提 ...

  9. 利用 Scrapy 爬取知乎用户信息

    思路:通过获取知乎某个大V的关注列表和被关注列表,查看该大V和其关注用户和被关注用户的详细信息,然后通过层层递归调用,实现获取关注用户和被关注用户的关注列表和被关注列表,最终实现获取大量用户信息. 一 ...

随机推荐

  1. 利用Javascript制作网页特效(其他常见特效)

    设置为首页和加入收藏夹 ①:在body标签内输入以下代码: <a onclick="this.style.behavior='url(#default#homepage)'; this ...

  2. BigDecimal 用法详解

    BigDecimal简介 BigDecimal用法: BigDecimal的构造方法 BigDecimal常用方法描述 BigDecimal比较 BigDecimal总结 BigDecimal简介 J ...

  3. 9. Linux用户身份和能力

    root 拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户.启动/关闭服务进程.开启/禁用硬件设备等.以root 管理员的身份工作时不会受到系统的限制 在Linux 系统中,UID 有唯 ...

  4. YOLOv1论文解读

    摘要 我们提出一种新的目标检测算法--YOLO.以前有关目标检测的研究将检测转化成分类器来执行.然而,我们将目标检测框架化为空间分隔的边界框及相关的类概率的回归问题.在一次评估中,单个神经网络直接从整 ...

  5. Git实践笔记(一)

    Git是什么 Git是目前世界上最先进的分布式版本控制系统. 工作原理 / 流程: Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remo ...

  6. CF Hello2020 D. New Year and Conference

    D. New Year and Conference 题意 有\(2n\)个区间,分别为\([sa_1,ea_1],[sb_1,eb_1],[sa_2,ea_2],[sb_2,eb_2],\cdots ...

  7. The 2019 ICPC Asia Shanghai Regional Contest H Tree Partition k、Color Graph

    H题意: 给你一个n个节点n-1条无向边构成的树,每一个节点有一个权值wi,你需要把这棵树划分成k个子树,每一个子树的权值是这棵子树上所有节点权值之和. 你要输出这k棵子树的权值中那个最大的.你需要让 ...

  8. c语言实现--单向循环链表操作

    1,什么叫单向循环链表.单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空. 2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头. 3,链表的结点表示 1 ...

  9. 【noi 2.6_8787】数的划分(DP){附【转】整数划分的解题方法}

    题意:问把整数N分成K份的分法数.(与"放苹果"不同,在这题不可以有一份为空,但可以类比)解法:f[i][j]表示把i分成j份的方案数.f[i][j]=f[i-1][j-1](新开 ...

  10. Codeforces Round #681 (Div. 1, based on VK Cup 2019-2020 - Final) B. Identify the Operations (模拟,双向链表)

    题意:给你一组不重复的序列\(a\),每次可以选择一个数删除它左边或右边的一个数,并将选择的数append到数组\(b\)中,现在给你数组\(b\),问有多少种方案数得到\(b\). 题解:我们可以记 ...