赞
踩
主要目的是对scrapy框架实战进行基础的认识,最详细的巩固scrapy框架使用流程。
目录
Note:这篇文章是对第一次完整使用scrapy框架进行项目实践的详细记载。本次操作页面是当当网书籍界面,目标是爬取100页所有书籍的名称、图片,还有价格。
1.打开cmd,进入想创建项目文件的位置对项目进行创建。
创建爬虫的项目命令: scrapy startproject 项目的名字
注意:项目的名字不允许使用数字开头 也不能包含中文
scrapy startproject scrapy_dangdang_04
进入到创建的项目文件中:cd 项目的名字\项目的名字\spiders
cd scrapy_dangdang_04\scrapy_dangdang_04\spiders
创建爬虫文件:(要在spiders文件夹中去创建爬虫文件)
scrapy genspider 爬虫文件的名字 要爬取网页
scrapy genspider dang https://category.dangdang.com/cp01.01.07.00.00.00.html
一般情况下不需要添加http协议 因为start_urls的值是根据allowed_domains修改的,所以添加了http的话 那么start_urls需要我们手动修改(新版无这个要求)
项目创建完毕:(顺便了解一下项目结构)
- scrapy项目的结构
- 项目名字
- 项目名字
- spiders文件夹(存储的是爬虫文件)
- init
- 自定义的爬虫文件 核心功能文件
- init
- items 定义数据结构的地方 爬取的数据都包含哪些
- middlewares 中间件 代理
- pipelines 管道 用来处理下载的数据
- settings 配置文件 robots协议 ua定义等
首先在items.py文件中定义文件结构,即你要下载的数据:
借助xpath工具得到所需要的路径:
- src = //ul[@id="component_59"]/li/a/img/@src
- name = //ul[@id="component_59"]/li/a/img/@alt
- price = //ul[@id="component_59"]/li/p[@class="price"]/span[1]/text()
我们发现三个路径有共同的部分,所有我们可以解析共同的部分,再解析不同的部分。所有selector对象可以再次调用xpath方法。
li_list = response.xpath('//ul[@id="component_59"]/li')
通过遍历获取需要的数据:
- for li in li_list:
- src = li.xpath('./a/img/@data-original').extract_first()
- #第一张图片和其他图片的标签属性不同,第一张图片src正常使用,其他图片地址为data-original
- if src:
- src = src
- else:
- src = li.xpath('./a/img/@src').extract_first()
- name = li.xpath('./a/img/@alt').extract_first()
- price = li.xpath('./p[@class="price"]/span[1]/text()').extract_first()
- print(src,name,price)
注意:图片地址路径改变为data-original的原因,涉及到懒加载的问题。不然使用原路径,除第一张图片,其他都为none,但使用新路径后,第一张返回none,所以我们需要加入一个判断语句,如果返回的src是true,则都赋新地址,否则为第一张图片返回none,将原地址赋给src。
在dang.py中导入items中接收数据的函数:
from scrapy_dangdang_04.items import ScrapyDangdang04Item
创建对象book
book = ScrapyDangdang04Item(src=src,name=name,price=price)
将获取到的数据发送给pipelines(获取一个返回值,将数据交给pipelines)
yield book
使用管道,必须在settings中开启
开启后再pipelines.py中写入内容
方法一:可以用with open()方法,但不推荐,因为操作过于频繁。w模式,会每一个对象打开一次文件,然后覆盖之前的内容 需要用a追加。
- with open('book.json','a',encoding='utf-8')as fp:
- fp.write(str(item))
方法二:企业开发通常,在爬虫文件开始前和结束后分别写入对应方法打开或关闭文件,避免重复打开文件。写入数据后,最后返回item。
- #在爬虫文件开始之前执行的打开文件方法
- def open_spider(self,spider):
- self.fp = open('book.json','w',encoding='utf-8')
- #在爬虫文件执行完成之后执行关闭文件方法
- def close_spider(self, spider):
- self.fp.close()
- def process_item(self, item, spider):
-
-
- self.fp.write(str(item))
-
- return item
(1)定义管道类
(2)在settings中开启管道
- import urllib.request
- #"scrapy_dangdang_04.pipelines.DangDangDownloadPipeline": 301
- class 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
在这里,我们导入urllib包,使用urlretrieve()来下载图片到books文件夹中。
首先分析每一页网站地址:(变动的只有pg后的数字)
每一页爬取的业务逻辑是相同的,所以我们只需要将执行的那个页面的请求再次调用parse方法就可。
第二页https://category.dangdang.com/pg2-cp01.01.07.00.00.00.html
第三页https://category.dangdang.com/pg3-cp01.01.07.00.00.00.html
所以先定义一个初始地址:
- base_url = 'https://category.dangdang.com/pg'
- page = 1
- if self.page < 100:
- self.page += 1
-
- url = self.base_url + str(self.page) + '-cp01.01.07.00.00.00.html'
因为第一页爬取完成,我们需要后面页码的url,在每次page后面+1
yield scrapy.Request(url=url,callback=self.parse)
在这里调用parse方法,scrapy.Request就是scrapy的get请求,url请求地址,注意callback是要执行的函数,不需要加()。
最后将数据发送到pipelines.py进行下载。
scrapy crawl dang
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。