目标是爬取某一系列图书的信息,例如名称、价格、图片等。

一、创建scrapy项目

在PyCharm终端依次输入:

  1. scrapy startproject dangdang
  2. cd dangdang\dangdang
  3. scrapy genspider dang category.dangdang.com/cp01.25.16.00.00.00.html

注:genspider后面的网址不需要带http://和url最后的斜线,如果带上需要去dangdang.py将start_urls手动修改为正确的url。.html的网页末尾一定不要有‘/’

之后测试一下这个url有没有robots协议或者反爬手段等,将parse函数改为输出一行文字,终端scrapy crawl dang发现运行成功,出现这行文字,连君子协议都没有。


二、items.py中定义数据的结构

通俗的说就是定义要下载的数据都有什么

给的案例是name = scrapy.Field(),定义完成的items.py如下

import scrapyclass DangdangItem(scrapy.Item):src = scrapy.Field()  # 图片name = scrapy.Field()  # 书名price = scrapy.Field()  # 价格

三、定位、爬取数据

分析网页源代码,我们需要的数据在如下的标签中

用xpath解析找到三个我们需要的信息

        src = //ul[@id="component_59"]//li//img/@srcname = //ul[@id="component_59"]//li//img/@altprice = //ul[@id="component_59"]//li//p[@class="price"]/span[1]/text()

在这里有个小技巧,所有的selector对象都可以再次调用xpath,所以我们可以这样写:

    def parse(self, response):target_list = response.xpath('//ul[@id="component_59"]//li')for t in target_list:src = t.xpath('.//img/@src').extract_first()name = t.xpath('.//img/@alt').extract_first()price = t.xpath('.//p[@class="price"]/span[1]/text()').extract_first()print(src, name, price)

运行测试,暂时的输出结果如下。发现其他正常,图片的src除了第一个都是none.jpg,说明做了反爬(大概率是图片的懒加载)

分析其余59本书的图片发现,果然src的地址都一样,但当页面滑动到加载那张图片时,图片的src会立马变成data-original里面的地址,这也是懒加载的一种方式。

但还要注意,第一张图片没有做懒加载,所以需要一个判读语句,完整代码如下:

    def parse(self, response):target_list = response.xpath('//ul[@id="component_59"]//li')for t in target_list:src = t.xpath('.//img/@data-original').extract_first()if src is None:src = t.xpath('.//img/@src').extract_first()else:src = srcname = t.xpath('.//img/@alt').extract_first()price = t.xpath('.//p[@class="price"]/span[1]/text()').extract_first()print(src, name, price)

四、保存数据到管道

接上,在刚才for循环的最后,首先存到一个book对象里,然后每创建一个就交给管道一个。这里的DangdangItem即在items.py中我们定义数据的结构的地方,导入这个类即可。导入方法为from dangdang.items import DangdangItem 编译器会报错,不用管,没关系!!!

         ......name = t.xpath('.//img/@alt').extract_first()price = t.xpath('.//p[@class="price"]/span[1]/text()').extract_first()book = DangdangItem(src=src, name=name, price=price)# 获取一个book就将一个book交给pipelinesyield book

之后我们需要用到管道,但必须要先在settings.py中设置开启管道,将settings中的如下代码行解开注释即可(这里的300代表优先级,优先级数值范围是1-1000,值越低优先级越高)。

ITEM_PIPELINES = {'dangdang.pipelines.DangdangPipeline': 300,
}

最后在pipelines.py中保存爬取数据,这里有两种写法。

首先第一种,因为yield是迭代器,产生一个book就交到pipelines执行一次process_item函数,所以文件会好多次被打开。

  1. 这里的写入模式我们不能用’w’,否则会被覆盖。
  2. write方法必须要写入str字符串类型,所以要强转
class DangdangPipeline:# item就是yield传来的book对象def process_item(self, item, spider):with open('book.json', 'a', encoding='utf-8') as f:f.write(str(item))return item

第二种,借助open_spider()和close_spider()函数。仅打开一次文件,保持打开状态,每个book不断写入,最后关闭文件。

class DangdangPipeline:# 在爬虫文件执行开始前,执行的函数def open_spider(self, spider):self.f = open('book.json', 'w', encoding='utf-8')# item就是yield传来的book对象def process_item(self, item, spider):self.f.write(str(item))return item# 在爬虫文件执行完后,执行的函数def close_spider(self, spider):self.f.close()

推荐第二种方式,因为第一种方式对文件的操作过于频繁,需要开关文件次数太多


五、多条管道下载

只需模仿DangdangPipeline类另写一个类,再在settings.py中开启管道即可

import urllib.requestclass DangdangDownloadPipeline:def process_item(self, item, spider):url = 'http:' + item.get('src')filename = './books/' + item.get('name') + '.jpg'urllib.request.urlretrieve(url=url, filename=filename)return item
ITEM_PIPELINES = {'dangdang.pipelines.DangdangPipeline': 300,'dangdang.pipelines.DangdangDownloadPipeline': 301
}

六、多页数据的下载

分析第一页、第二页、第三页的url发现很相似,只是pg后面的数字在改变

我们的代码逻辑没有变,只有url在改变
所以我们需要改变页码,然后不断回调parse函数执行相同的逻辑。dang.py完整代码如下:

import scrapy
from dangdang.items import DangdangItemclass DangSpider(scrapy.Spider):name = 'dang'# 如果多页下载,需要调整allowed_domains的范围,一般情况下只写域名allowed_domains = ['category.dangdang.com']start_urls = ['http://category.dangdang.com/cp01.25.16.00.00.00.html']base_url = 'http://category.dangdang.com/pg'page = 1def parse(self, response):target_list = response.xpath('//ul[@id="component_59"]//li')for t in target_list:src = t.xpath('.//img/@data-original').extract_first()if src is None:src = t.xpath('.//img/@src').extract_first()else:src = srcname = t.xpath('.//img/@alt').extract_first()price = t.xpath('.//p[@class="price"]/span[1]/text()').extract_first()book = DangdangItem(src=src, name=name, price=price)# 获取一个book就将一个book交给pipelinesyield bookif self.page < 100:self.page = self.page + 1url = self.base_url + str(self.page) + '-cp01.25.16.00.00.00.html'# 调用parse方法# scrapy.Request就是scrapy的get请求, url是请求地址,callback是要执行的函数yield scrapy.Request(url=url, callback=self.parse)

yield可以让parse函数不断在回调自己。


七、其他代码

Items.py

import scrapyclass DangdangItem(scrapy.Item):src = scrapy.Field()  # 图片name = scrapy.Field()  # 书名price = scrapy.Field()  # 价格

pipelines.py

from itemadapter import ItemAdapterclass DangdangPipeline:# 在爬虫文件执行开始前,执行的函数def open_spider(self, spider):self.f = open('book.json', 'w', encoding='utf-8')# item就是yield传来的book对象def process_item(self, item, spider):self.f.write(str(item))return item# 在爬虫文件执行完后,执行的函数def close_spider(self, spider):self.f.close()import urllib.requestclass DangdangDownloadPipeline:def process_item(self, item, spider):url = 'http:' + item.get('src')filename = './books/' + item.get('name') + '.jpg'urllib.request.urlretrieve(url=url, filename=filename)return item

步骤总结

  1. 创建scrapy项目
  2. 在items.py中定义所需数据的结构
  3. 利用response.xpath定位爬取数据
  4. 利用管道下载数据:首先创建一个要存储的对象book = DangdangItem(src=src, name=name, price=price)。然后用yield将其逐个交给pipelines。然后在settings.py里开启管道。pipelines.py中的process_item函数中的item就是这里的book对象。在这里面操作并存储数据。
  5. 多管道下载只需在pipelines.py中再定义一个类,同样也需要开启管道。
  6. 下载多页数据需要先设置一个页码变量,在parse函数中回调自己,过程中页码加一。需要用到yield关键字和scrapy.Request(url=url, callback=self.parse),即scrapy的get请求,callback是回调的函数名,不需要加括号。

Python 爬虫学习笔记(十(2))scrapy爬取图书电商实战详解相关推荐

  1. python爬虫学习笔记(一)—— 爬取腾讯视频影评

    前段时间我忽然想起来,以前本科的时候总有一些公众号,能够为我们提供成绩查询.课表查询等服务.我就一直好奇它是怎么做到的,经过一番学习,原来是运用了爬虫的原理,自动登陆教务系统爬取的成绩等内容.我觉得挺 ...

  2. 爬虫学习笔记-猫眼电影排行爬取

    爬虫学习笔记-猫眼电影排行爬取 1 分析页面 https://maoyan.com/board/4 点击页码发现页面的URL变成: 初步推断出offset是一个偏移量的参数,当页面为第一页时offse ...

  3. Python爬虫学习基础——5分钟学会爬取B站视频日播放量排行

    Python爬虫学习基础--5分钟学会爬取B站视频日播放量排行 基础包含 requests pyquery 进入正题 基础包含 这也是我当初第一次学习爬虫时做的练习,感觉给初学者练笔挺不错的.运用的知 ...

  4. Python爬虫学习 6 —— 使用bs4库爬取大学排名

    前面学了如何使用beautifulsoup,现在来尝试简单的爬取:中国大学排名 一.准备 查看Robots协议:robots协议 功能描述 输入:大学排名的url链接 输出:大学排名信息(排名,大学名 ...

  5. Python爬虫学习教程 bilibili网站视频爬取!【附源码】

    Python爬虫学习教程,万物皆可爬!每个技术大牛都是从基础慢慢的提升上去的,基础知识越深以后的发展越牛!学好python,才能玩转python,那到底怎么才能学好python? 通过爬取b站案例带领 ...

  6. Python数据爬虫学习笔记(11)爬取千图网图片数据

    需求:在千图网http://www.58pic.com中的某一板块中,将一定页数的高清图片素材爬取到一个指定的文件夹中. 分析:以数码电器板块为例 1.查看该板块的每一页的URL: 注意到第一页是&q ...

  7. python爬取京东手机数据_Python数据爬虫学习笔记(21)爬取京东商品JSON信息并解析...

    一.需求:有一个通过抓包得到的京东商品的JSON链接,解析该JSON内容,并提取出特定id的商品价格p,json内容如下: jQuery923933([{"op":"75 ...

  8. Python爬虫实习笔记 | Week4 项目数据爬取与反思

    2018/11/05 1.所思所想: 今天我把Python爬虫实战这本书Chapter6看完,很有感触的一点是,书本中对爬虫实现的模块化设计很给我灵感,让我对项目中比较无语的函数拼接有了解决之道,内省 ...

  9. 【Python3 爬虫学习笔记】用PySpider爬取虎嗅网并进行文章分析

    –转自<1900-高级农民工>http://www.makcyun.top 安装并运行pyspider 安装pyspider pip3 install pyspider 运行pyspide ...

最新文章

  1. Android 动画小知识点
  2. matlab内将数组内所有数累乘,数学实验上机汇总【未完成】
  3. mysql 唯一键和主键_MySQL唯一键和主键
  4. oracle重命名日志成员出错,Oracle日志文件
  5. java线程池并发_Java并发教程–线程池
  6. 寻找随机的错误-一个真实的故事
  7. ros c++ 代码说明文档_减少运维工作量,如何通过 ROS 轻松实现资源编排新方式...
  8. MVC,MVP,MVVM
  9. KubeEdge 1.3.0 部署
  10. Spark的动态资源分配ExecutorAllocationManager
  11. Python爬虫进阶之某支付网站密码分析
  12. uni-app项目实现用户注册密码前端页面加密
  13. OpenCV:Mat创建全白图、全黑图、指定像素值的图
  14. 最全收集整理GitHub上受欢迎的Android UI Library
  15. 超融合产品的优势和适用场景
  16. 沪江日语小D落户博客园~
  17. Day 10 你喜欢合租还是独居
  18. 你刷我,我刷你,霸榜CLUE甜蜜蜜
  19. 《下一代互联网(IPv6)搭建与运维》
  20. idea向github传文件

热门文章

  1. Python-各种Loss总结
  2. 不恰当使用线程池处理 MQ 消息引起的故障
  3. incsgo 可直接立刻取回皮肤的CSGO饰品皮肤开箱网站
  4. 单层神经网络实现手写数字识别
  5. 数据库高并发和高可用方案
  6. 货拉拉2021岗位招聘内推计划开始啦
  7. mysql load 导入csv或者unl 如果文件跟表的字段不一致的情况
  8. 美颜API是什么意思?美颜API和美颜SDK有什么区别?
  9. 【Java--名片管理系统】
  10. Type-C口充电器头为什么没有电压输出?