Python 爬虫学习笔记(十(2))scrapy爬取图书电商实战详解
目标是爬取某一系列图书的信息,例如名称、价格、图片等。
一、创建scrapy项目
在PyCharm终端依次输入:
- scrapy startproject dangdang
- cd dangdang\dangdang
- 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函数,所以文件会好多次被打开。
- 这里的写入模式我们不能用’w’,否则会被覆盖。
- 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
步骤总结
- 创建scrapy项目
- 在items.py中定义所需数据的结构
- 利用response.xpath定位爬取数据
- 利用管道下载数据:首先创建一个要存储的对象book = DangdangItem(src=src, name=name, price=price)。然后用yield将其逐个交给pipelines。然后在settings.py里开启管道。pipelines.py中的process_item函数中的item就是这里的book对象。在这里面操作并存储数据。
- 多管道下载只需在pipelines.py中再定义一个类,同样也需要开启管道。
- 下载多页数据需要先设置一个页码变量,在parse函数中回调自己,过程中页码加一。需要用到yield关键字和scrapy.Request(url=url, callback=self.parse),即scrapy的get请求,callback是回调的函数名,不需要加括号。
Python 爬虫学习笔记(十(2))scrapy爬取图书电商实战详解相关推荐
- python爬虫学习笔记(一)—— 爬取腾讯视频影评
前段时间我忽然想起来,以前本科的时候总有一些公众号,能够为我们提供成绩查询.课表查询等服务.我就一直好奇它是怎么做到的,经过一番学习,原来是运用了爬虫的原理,自动登陆教务系统爬取的成绩等内容.我觉得挺 ...
- 爬虫学习笔记-猫眼电影排行爬取
爬虫学习笔记-猫眼电影排行爬取 1 分析页面 https://maoyan.com/board/4 点击页码发现页面的URL变成: 初步推断出offset是一个偏移量的参数,当页面为第一页时offse ...
- Python爬虫学习基础——5分钟学会爬取B站视频日播放量排行
Python爬虫学习基础--5分钟学会爬取B站视频日播放量排行 基础包含 requests pyquery 进入正题 基础包含 这也是我当初第一次学习爬虫时做的练习,感觉给初学者练笔挺不错的.运用的知 ...
- Python爬虫学习 6 —— 使用bs4库爬取大学排名
前面学了如何使用beautifulsoup,现在来尝试简单的爬取:中国大学排名 一.准备 查看Robots协议:robots协议 功能描述 输入:大学排名的url链接 输出:大学排名信息(排名,大学名 ...
- Python爬虫学习教程 bilibili网站视频爬取!【附源码】
Python爬虫学习教程,万物皆可爬!每个技术大牛都是从基础慢慢的提升上去的,基础知识越深以后的发展越牛!学好python,才能玩转python,那到底怎么才能学好python? 通过爬取b站案例带领 ...
- Python数据爬虫学习笔记(11)爬取千图网图片数据
需求:在千图网http://www.58pic.com中的某一板块中,将一定页数的高清图片素材爬取到一个指定的文件夹中. 分析:以数码电器板块为例 1.查看该板块的每一页的URL: 注意到第一页是&q ...
- python爬取京东手机数据_Python数据爬虫学习笔记(21)爬取京东商品JSON信息并解析...
一.需求:有一个通过抓包得到的京东商品的JSON链接,解析该JSON内容,并提取出特定id的商品价格p,json内容如下: jQuery923933([{"op":"75 ...
- Python爬虫实习笔记 | Week4 项目数据爬取与反思
2018/11/05 1.所思所想: 今天我把Python爬虫实战这本书Chapter6看完,很有感触的一点是,书本中对爬虫实现的模块化设计很给我灵感,让我对项目中比较无语的函数拼接有了解决之道,内省 ...
- 【Python3 爬虫学习笔记】用PySpider爬取虎嗅网并进行文章分析
–转自<1900-高级农民工>http://www.makcyun.top 安装并运行pyspider 安装pyspider pip3 install pyspider 运行pyspide ...
最新文章
- Android 动画小知识点
- matlab内将数组内所有数累乘,数学实验上机汇总【未完成】
- mysql 唯一键和主键_MySQL唯一键和主键
- oracle重命名日志成员出错,Oracle日志文件
- java线程池并发_Java并发教程–线程池
- 寻找随机的错误-一个真实的故事
- ros c++ 代码说明文档_减少运维工作量,如何通过 ROS 轻松实现资源编排新方式...
- MVC,MVP,MVVM
- KubeEdge 1.3.0 部署
- Spark的动态资源分配ExecutorAllocationManager
- Python爬虫进阶之某支付网站密码分析
- uni-app项目实现用户注册密码前端页面加密
- OpenCV:Mat创建全白图、全黑图、指定像素值的图
- 最全收集整理GitHub上受欢迎的Android UI Library
- 超融合产品的优势和适用场景
- 沪江日语小D落户博客园~
- Day 10 你喜欢合租还是独居
- 你刷我,我刷你,霸榜CLUE甜蜜蜜
- 《下一代互联网(IPv6)搭建与运维》
- idea向github传文件